从docker到istio之四:istio管理应用

Posted by hiho on November 20, 2020

istio

服务网格(Service Mesh)这个术语通常用于描述构成这些应用程序的微服务网络以及应用之间的交互。随着规模和复杂性的增长,服务网格越来越难以理解和管理。它的需求包括服务发现、负载均衡、故障恢复、指标收集和监控以及通常更加复杂的运维需求,例如 A/B 测试、金丝雀发布、限流、访问控制和端到端认证等。 Istio 提供了一个完整的解决方案,通过为整个服务网格提供行为洞察和操作控制来满足微服务应用程序的多样化需求。

安装istio

下载安装istio

1、在 macOS 或 Linux 系统中,也可以通过以下命令下载最新版本的 Istio:

curl -L https://istio.io/downloadIstio | sh -

2、指定版本

curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.6.8 TARGET_ARCH=x86_64 sh -

3、切换到 Istio 包所在目录下。例如:Istio 包名为 istio-1.8.0,则:

cd istio-1.8.0

安装目录包含如下内容:

  • samples/ 目录下,有示例应用程序
  • bin/ 目录下,包含 istioctl 的客户端文件。

4、将istioctl客户端添加到您的路径(Linux或macOS):

export PATH=$PWD/bin:$PATH

5、在使用 bash 或 ZSH 控制台时,可以选择启动 auto-completion option

安装 Istio

1、对于此安装,我们使用demo 配置文件。选择它具有一组很好的测试默认值,但还有其他用于生产或性能测试的配置文件。

$ istioctl install --set profile=demo -y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete

2、添加名称空间标签,以指示Istio在以后部署应用程序时自动注入Envoy sidecar代理:

$ kubectl label namespace default istio-injection=enabled
namespace/default labeled

kubectl get svc -n istio-system 查看isto服务(svc是service的速记别名)

1.png

查看isto的pod是否全部正常启动:

➜ kubectl get pods -n istio-system
NAME                                    READY   STATUS    RESTARTS   AGE
grafana-784c89f4cf-9fw4h                1/1     Running   8          6d23h
istio-egressgateway-8dff9c778-6gcwx     1/1     Running   8          6d23h
istio-ingressgateway-6cfd75fc57-jrw47   1/1     Running   8          6d23h
istiod-7f6d7c759-h2g75                  1/1     Running   8          6d23h
jaeger-7f78b6fb65-6hbz9                 1/1     Running   8          6d23h
kiali-7476977cf9-7qt9n                  1/1     Running   7          6d23h
prometheus-7bfddb8dbf-mzzt9             2/2     Running   16         6d23h

使用istio部署应用

因为istio附带ingress,所以我们取消了前置的nginx负载,直接使用ingress。

启动istio的sidecar自动注入

istio通过在pod中输入sidecar,用来管理流量,设置default名称空间下默认注入:

➜  docker2istio kubectl label namespace default istio-injection=enabled
namespace/default labeled

启动服务

启动服务方式和k8s没有区别

kubectl apply -f k8s/redis.yaml -f k8s/laravelapp.yaml
service/docker2istio-redis created
deployment.apps/docker2istio-redis created
service/docker2istio-app created
deployment.apps/docker2istio-app created
➜  ~ kubectl get pod 
NAME                                  READY   STATUS    RESTARTS   AGE
details-v1-79c697d759-vwggb           2/2     Running   15         6d23h
docker2istio-app-6564f8d748-c54t5     2/2     Running   0          81s
docker2istio-app-6564f8d748-dhts9     2/2     Running   0          81s
docker2istio-app-6564f8d748-htnq8     2/2     Running   0          81s
docker2istio-redis-6666d9f767-mvr7d   2/2     Running   0          81s
.....

使用kubectl describe pod/docker2istio-app-6564f8d748-c54t5 确认istio正常管理app:

Name:         docker2istio-app-6564f8d748-c54t5
Namespace:    default
Priority:     0
Node:         docker-desktop/192.168.65.3
Start Time:   Fri, 27 Nov 2020 14:50:11 +0800
Labels:       app=docker2istio-app
              istio.io/rev=default
              pod-template-hash=6564f8d748
              security.istio.io/tlsMode=istio
              service.istio.io/canonical-name=docker2istio-app
              service.istio.io/canonical-revision=v1
              version=v1
Annotations:  prometheus.io/path: /stats/prometheus
              prometheus.io/port: 15020
              prometheus.io/scrape: true
              sidecar.istio.io/status:
                {"version":"e2cb9d4837cda9584fd272bfa1f348525bcaacfadb7e9b9efbd21a3bb44ad7a1","initContainers":["istio-init"],"containers":["istio-proxy"]...
Status:       Running
IP:           10.1.1.102
IPs:
  IP:           10.1.1.102
Controlled By:  ReplicaSet/docker2istio-app-6564f8d748
Init Containers:
  istio-init:
    Container ID:  docker://efcb18807b711f147d6918b50d26d07713a7095b874723ab1877d09014ba8a01
    Image:         docker.io/istio/proxyv2:1.8.0
    Image ID:      docker-pullable://istio/proxyv2@sha256:8721ddb5acf86dbe9d4c68993947c27d4b98a6d23ecde80246c74bf8bebd163f
    Port:          <none>
    Host Port:     <none>
    Args:
      istio-iptables
      -p
      15001
      -z
      15006
      -u
      1337
      -m
      REDIRECT
      -i
      *
      -x
      
      -b
      *
      -d
      15090,15021,15020
    State:          Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Fri, 27 Nov 2020 14:50:48 +0800
      Finished:     Fri, 27 Nov 2020 14:50:49 +0800
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     2
      memory:  1Gi
    Requests:
      cpu:     10m
      memory:  40Mi
    Environment:
      DNS_AGENT:  
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-lshqn (ro)
Containers:
  docker2istio-app:
    Container ID:   docker://2bbdb747caac8fa4dfebf42cde03410e3b4e38e48c1f1538519482312d559aaf
    Image:          laravelapp:0.0.2
    Image ID:       docker://sha256:a650e4a53b2616d6fecdcbd32d99496f8960eba85748182d7604bb539fb4f3fd
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Fri, 27 Nov 2020 14:50:50 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-lshqn (ro)
  istio-proxy:
    Container ID:  docker://b607906fc699b859ce3cc90d78a957cc4d155be2895caf47e6735ec815e5ba49
    Image:         docker.io/istio/proxyv2:1.8.0
    Image ID:      docker-pullable://istio/proxyv2@sha256:8721ddb5acf86dbe9d4c68993947c27d4b98a6d23ecde80246c74bf8bebd163f
    Port:          15090/TCP
    Host Port:     0/TCP
    Args:
      proxy
      sidecar
      --domain
      $(POD_NAMESPACE).svc.cluster.local
      --serviceCluster
      docker2istio-app.$(POD_NAMESPACE)
      --proxyLogLevel=warning
      --proxyComponentLogLevel=misc:error
      --concurrency
      2
    State:          Running
      Started:      Fri, 27 Nov 2020 14:51:21 +0800
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     2
      memory:  1Gi
    Requests:
      cpu:      10m
      memory:   40Mi
    Readiness:  http-get http://:15021/healthz/ready delay=1s timeout=3s period=2s #success=1 #failure=30
    Environment:
      JWT_POLICY:                    first-party-jwt
      PILOT_CERT_PROVIDER:           istiod
      CA_ADDR:                       istiod.istio-system.svc:15012
      POD_NAME:                      docker2istio-app-6564f8d748-c54t5 (v1:metadata.name)
      POD_NAMESPACE:                 default (v1:metadata.namespace)
      INSTANCE_IP:                    (v1:status.podIP)
      SERVICE_ACCOUNT:                (v1:spec.serviceAccountName)
      HOST_IP:                        (v1:status.hostIP)
      CANONICAL_SERVICE:              (v1:metadata.labels['service.istio.io/canonical-name'])
      CANONICAL_REVISION:             (v1:metadata.labels['service.istio.io/canonical-revision'])
      PROXY_CONFIG:                  {"proxyMetadata":{"DNS_AGENT":""}}
                                     
      ISTIO_META_POD_PORTS:          [
                                         {"containerPort":8080,"protocol":"TCP"}
                                     ]
      ISTIO_META_APP_CONTAINERS:     docker2istio-app
      ISTIO_META_CLUSTER_ID:         Kubernetes
      ISTIO_META_INTERCEPTION_MODE:  REDIRECT
      ISTIO_META_WORKLOAD_NAME:      docker2istio-app
      ISTIO_META_OWNER:              kubernetes://apis/apps/v1/namespaces/default/deployments/docker2istio-app
      ISTIO_META_MESH_ID:            cluster.local
      TRUST_DOMAIN:                  cluster.local
      DNS_AGENT:                     
    Mounts:
      /etc/istio/pod from istio-podinfo (rw)
      /etc/istio/proxy from istio-envoy (rw)
      /var/lib/istio/data from istio-data (rw)
      /var/run/secrets/istio from istiod-ca-cert (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-lshqn (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-lshqn:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-lshqn
    Optional:    false
  istio-envoy:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     Memory
    SizeLimit:  <unset>
  istio-data:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  <unset>
  istio-podinfo:
    Type:  DownwardAPI (a volume populated by information about the pod)
    Items:
      metadata.labels -> labels
      metadata.annotations -> annotations
  istiod-ca-cert:
    Type:        ConfigMap (a volume populated by a ConfigMap)
    Name:        istio-ca-root-cert
    Optional:    false
QoS Class:       Burstable
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  2m7s  default-scheduler  Successfully assigned default/docker2istio-app-6564f8d748-c54t5 to docker-desktop
  Normal  Pulling    2m5s  kubelet            Pulling image "docker.io/istio/proxyv2:1.8.0"
  Normal  Pulled     90s   kubelet            Successfully pulled image "docker.io/istio/proxyv2:1.8.0" in 34.930504729s
  Normal  Created    90s   kubelet            Created container istio-init
  Normal  Started    90s   kubelet            Started container istio-init
  Normal  Pulled     88s   kubelet            Container image "laravelapp:0.0.2" already present on machine
  Normal  Created    88s   kubelet            Created container docker2istio-app
  Normal  Started    88s   kubelet            Started container docker2istio-app
  Normal  Pulling    88s   kubelet            Pulling image "docker.io/istio/proxyv2:1.8.0"
  Normal  Pulled     58s   kubelet            Successfully pulled image "docker.io/istio/proxyv2:1.8.0" in 30.733066889s
  Normal  Created    57s   kubelet            Created container istio-proxy
  Normal  Started    57s   kubelet            Started container istio-proxy

!!!注意 这里的pod,会被自动注入名为istio-init的initContainer和名为**istio-proxy的container。具有这2个container,标志pod接受istio流量管理。

确认服务正常启动

➜  docker2istio kubectl get svc
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
details              ClusterIP   10.107.222.87    <none>        9080/TCP   6d23h
docker2istio-app     ClusterIP   10.104.44.7      <none>        8080/TCP   5m32s
docker2istio-redis   ClusterIP   10.107.104.202   <none>        6379/TCP   5m33s
kubernetes           ClusterIP   10.96.0.1        <none>        443/TCP    12d

确认pod正常启动

➜  docker2istio kubectl get pod
NAME                                  READY   STATUS    RESTARTS   AGE
details-v1-79c697d759-vwggb           2/2     Running   15         6d23h
docker2istio-app-6564f8d748-c54t5     2/2     Running   0          6m1s
docker2istio-app-6564f8d748-dhts9     2/2     Running   0          6m1s
docker2istio-app-6564f8d748-htnq8     2/2     Running   0          6m1s
docker2istio-redis-6666d9f767-mvr7d   2/2     Running   0          6m1s

部署istio的gateway

因为取消了前置的nginx负载,需要设置gateway,集群外部才能够访问服务。istio\gateway.yaml:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: docker2istio-app-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: laravelapp
spec:
  hosts:
  - "*"
  gateways:
  - docker2istio-app-gateway
  http:
  - match:
    - uri:
        exact: /
    route:
    - destination:
        host: docker2istio-app
        port:
          number: 8080

kubectl apply -f istio/gateway.yaml提交后,查看gateway的端口:

➜  kubectl get svc istio-ingressgateway -n istio-system
NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                                      AGE
istio-ingressgateway   LoadBalancer   10.104.56.91   localhost     15021:30000/TCP,80:31387/TCP,443:30293/TCP,31400:30573/TCP,15443:32429/TCP   7d

这里的服务类型为LoadBalancer,可以直接使用80端口访问服务:

➜  docker2istio curl http://localhost
Hello World by 127.0.0.1 from 10.1.1.102 ! 该页面已被访问 1 次。
➜  docker2istio curl http://localhost
Hello World by 127.0.0.1 from 10.1.1.102 ! 该页面已被访问 2 次。
➜  docker2istio curl http://localhost
Hello World by 127.0.0.1 from 10.1.1.102 ! 该页面已被访问 3 次。
➜  docker2istio curl http://localhost
Hello World by 127.0.0.1 from 10.1.1.100 ! 该页面已被访问 4 次。
➜  docker2istio curl http://localhost
Hello World by 127.0.0.1 from 10.1.1.100 ! 该页面已被访问 5 次。
➜  docker2istio curl http://localhost
Hello World by 127.0.0.1 from 10.1.1.101 ! 该页面已被访问 6 次。

—End—

迭代

  • 2020年11月27日 16:30 初稿

参考