istio 三日谈之一: 环境准备

尝试在一个准生产环境下,利用 istio 来对运行在 Kubernetes 上的微服务进行管理。

这一篇是第一篇,将一些主要的坑和环境准备工作。

内容较多,因此无法写成手把手教程,希望读者有一定 Kubernetes 的操作基础。

准备镜像

初始运行需要的镜像包括以下几个:

  • istio/mixer:0.1.6
  • pilot:0.1.6
  • proxy_debug:0.1.6
  • istio-ca:0.1.6

首先要解决的自然还是镜像的存放问题,官方在源码中提供了很方便的工具,用来根据模板生成在 Kubernetes 中运行 istio 的 YAML 文件:

./updateVersion.sh \
    -p 10.211.55.86:5000/istio,0.1.6 \
    -c 10.211.55.86:5000/istio,0.1.6 \
    -x 10.211.55.86:5000/istio,0.1.6

这一脚本在源码的 install 目录下。

Kubernetes 环境

这里我们使用的集群大概情况是:

  • 1.7.1 版本的 Kubernetes
  • 开启了 RBAC
  • 预备使用的命名空间为:default
  • PVC 自动供给
  • 无互联网连接
  • 具有自己的私库

启动 istio

RBAC 相关

首先,install 目录中提供的 rbac 文件授权范围不足,所以需要手工编辑istio-rbac-beta.yaml,把其中的几个 RoleBinding,改为 ClusterRoleBinding。

kubectl create \
    -f istio-rbac-beta.yaml

另外缺省的 ClusterRole 中缺乏对 Namespace 的权限,新版本已经修正,目前版本仍需添加:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: istio-pilot
rules:
- apiGroups: ["istio.io"]
  resources: ["istioconfigs", "istioconfigs.istio.io"]
  verbs: ["*"]
- apiGroups: ["extensions"]
  resources: ["thirdpartyresources", "thirdpartyresources.extensions", "ingresses", "ingresses/status"]
  verbs: ["*"]
- apiGroups: [""]
  resources: ["configmaps", "endpoints", "pods", "services"]
  verbs: ["*"]
- apiGroups: [""]
  resources: ["namespaces", "nodes", "secrets"]
  verbs: ["get", "list", "watch"]

启动 istio 组件

kubectl create \
    -f istio.yaml \

创建 PVC

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: frontend-v1
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

准备工作负载

这里我们使用官方的 PHP + Apache 镜像作为工作负载来进行下面的测试,例如我们准备好的 YAML 如下:

Deployment

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: frontend
  labels:
    name: frontend
    version: "1"
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: frontend
        version: "1"
    spec:
      containers:
      - name: php
        image: 10.211.55.86:5000/php:7.1.7-apache
        ports:
        - containerPort: 80
          protocol: TCP
        volumeMounts:
        - name: wwwroot
          mountPath: /var/www/html
        env:
        - name: "SERVICE_VERSION"
          value: "1"      
        volumes:
      - name: wwwroot
        persistentVolumeClaim:
          claimName: frontend-v1

服务定义:

kind: Service
apiVersion: v1
metadata:
  name: svc-frontend
  labels:
    name: frontend
    version: "1"
spec:
  type: NodePort
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 32010  
  selector:
    name: frontend

在 Web 目录中我们随便做了个index.php,用来展示当前所在 Pod 和环境变量中的服务版本号,备用。

Tips:一般这类测试,我都懒得重新做一个 Docker 镜像,一般是另外用一个 Pod 挂载同一个 PVC,直接编辑页面文件,或者使用kubectl cp命令进行拷贝。

index.php

<?php
header("Content-type: text/plain");
echo "From: ".gethostname()."\n";
echo "Version: ".$_ENV['SERVICE_VERSION']."\n";

delay.php

<?php
header("Content-type: text/plain");
sleep(4);
echo "\n-----------------------------\n";
echo "\nFrom: ".gethostname()."\n";
echo "Version: ".$_ENV['SERVICE_VERSION']."\n";

运行成功后,访问该服务的 nodePort,会看到相应的输出内容。

istio 的注入

首先用kubectl delete -f删除上文的服务和 Deployment。

上面为了测试方便,给 Service 使用了 NodePort 类型,这里我们去掉这一服务的 NodePort,用 ClusterIP 的形式运行:

spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  selector:
    name: frontend

接下来进行注入操作

istioctl kube-inject -f frontend-v1.yaml > frontend-v1-istio.yaml

观察注入操作会发现,其中多了一个 Sidecar Container(下面的 Image 节内容已经被我修改为本地私库):

    env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: POD_NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    image: 10.211.55.86:5000/istio/proxy_debug:0.1.6
    imagePullPolicy: Always
    name: proxy
    resources: {}
    securityContext:
      runAsUser: 1337

另外还在pod.beta.kubernetes.io/init-containers注解中进行了初始化:

[{
  "args": ["-p", "15001", "-u", "1337"],
  "image": "10.211.55.86:5000/istio/init:0.1",
  "imagePullPolicy": "Always",
  "name": "init",
  "securityContext": {
    "capabilities": {
      "add": ["NET_ADMIN"]
    }
  }
}, {
  "args": ["-c", "sysctl -w kernel.core_pattern=/tmp/core.%e.%p.%t \u0026\u0026 ulimit -c unlimited"],
  "command": ["/bin/sh"],
  "image": "10.211.55.86:5000/alpine",
  "imagePullPolicy": "Always",
  "name": "enable-core-dump",
  "securityContext": {
    "privileged": true
  }
}]

可以看到上面一共涉及三个镜像:

  • docker.io/istio/proxy_debug:0.1
  • docker.io/istio/init:0.1
  • alpine

经过一番折腾:

  1. 原有 YAML
  2. 注入,生成新的 YAML
  3. 替换新 YAML 中的镜像地址

就把原有的容器应用封装成新的 istio 支持的微服务了。

准备测试素材

另外我们需要准备一个工具服务,用于在 shell 中进行测试:

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: tool
  labels:
    name: tool
    version: "1"
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: tool
        version: "1"
    spec:
      containers:
      - name: tool
        image: 10.211.55.86:5000/php:7.1.7-apache
        ports:
        - containerPort: 80
          protocol: TCP
        volumeMounts:
        - name: wwwroot
          mountPath: /var/www/html
      volumes:
      - name: wwwroot
        persistentVolumeClaim:
          claimName: frontend-v1
---
kind: Service
apiVersion: v1
metadata:
  name: tool
  labels:
    name: tool
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  selector:
    name: tool

同样的,这里也需要执行istioctl kube-inject进行注入,运行之后,就得到一个运行于集群内部的 Linux Shell,istio 中的路由策略经常是客户端和服务器协同完成的,因此上客户和服务器的 Deployment 都需要进行注入操作。

K8S中文文档  docs.kubernetes.org.cn

转自:https://www.kubernetes.org.cn/2449.html

<think>好的,用户让我解释一个ServiceMonitor的配置,这个配置是用于监控Istio组件的。之前用户已经询问过如何配置ServiceMonitor和PodMonitor来监控Istio,并且现在提供了具体的YAML内容请求解释。我需要先仔细分析用户提供的YAML结构,然后逐部分解释每个字段的作用。 首先,用户提供的ServiceMonitor的apiVersion是monitoring.coreos.com/v1,这是Prometheus Operator的CRD,正确。metadata部分中的name和namespace都很清楚,但用户可能对labels的作用不太了解,需要说明这些标签可能用于Prometheus的选择器匹配。接下来是spec部分,jobLabel和targetLabels可能用户需要详细解释,特别是它们如何影响Prometheus的配置。 然后看selector部分,这里使用了matchExpressions,用户可能对In操作符的作用不太清楚,需要说明这是在选择具有特定标签的服务。namespaceSelector设置为any: true,这允许监控所有命名空间中的服务,但用户之前的问题中可能只需要监控istio-system,所以需要指出这里的配置是否合适,或者是否需要调整。 endpoints部分中的port名称是否正确?之前用户提到istiod的metrics端口是http-monitoring,所以这里应该没问题,但需要确认服务中是否有这个端口名称。interval设置为15秒,这可能会对Prometheus的负载产生影响,特别是如果监控目标很多的话,可能需要提醒用户根据实际情况调整。 另外,用户之前的问题中提到他们使用的是外部的Prometheus,所以需要确认Prometheus Operator的配置是否允许跨命名空间发现ServiceMonitor。例如,ServiceMonitor所在的命名空间(istio-system)是否在Prometheus的监控范围内,或者Prometheus是否配置了serviceMonitorNamespaceSelector来选择所有命名空间。 可能用户在实际应用中遇到的问题是ServiceMonitor没有正确被发现,导致指标无法抓取。需要指出关键点,比如命名空间选择器、标签匹配是否正确,以及端口名称是否与服务中的定义一致。此外,用户可能需要检查Prometheus的RBAC配置,确保有权限访问目标服务。 最后,用户可能需要验证配置是否生效,可以通过查看Prometheus的target页面,或者检查Prometheus的日志是否有错误。结合之前提供的验证步骤,提醒用户如何检查Target状态和查询指标,确保配置正确无误。</think>以下是对该ServiceMonitor配置的逐行解析及功能说明: ```yaml apiVersion: monitoring.coreos.com/v1 # 使用Prometheus Operator的CRD版本 kind: ServiceMonitor metadata: name: istio-component-monitor # 监控资源名称 namespace: istio-system # 必须与Prometheus配置允许发现的namespace匹配 labels: monitoring: istio-components # 标签用于Prometheus的自动发现筛选 release: istio # 通常关联Helm release名称 spec: jobLabel: istio # 在Prometheus job名称中复用Service的"istio"标签值 targetLabels: [app] # 将Service的"app"标签复制到监控指标 selector: matchExpressions: # 高级选择器(比matchLabels更灵活) - {key: istio, operator: In, values: [pilot]} # 选择带有istio=pilot标签的Service namespaceSelector: any: true # 监控所有命名空间中的目标(慎用!建议限定为istio-system) endpoints: - port: http-monitoring # 必须与Service中定义的端口名称完全匹配 interval: 15s # 抓取频率(生产环境建议30s) ``` 关键配置注意事项: 1. **标签匹配问题** - Istiod默认Service标签为`istio=pilot`,需执行验证: ```shell kubectl -n istio-system get svc -l istio=pilot # 预期输出应包含istiod服务 ``` - 若实际服务标签不符,可改用`app: istiod`等标签 2. **namespaceSelector风险** `any: true`会导致Prometheus扫描所有命名空间,可能引发: - 资源浪费(抓取无关数据) - 安全风险(暴露不应监控的服务) **建议修正为**: ```yaml namespaceSelector: matchNames: - istio-system # 精确限定命名空间 ``` 3. **端口名称验证** 必须确认istiod服务的端口定义: ```shell kubectl -n istio-system describe svc istiod | grep -A3 Ports # 应显示类似: # Port: http-monitoring 15014/TCP # TargetPort: 15014/TCP ``` 若端口名称不匹配,将产生`no endpoints found`错误 4. **与Prometheus的关联性** 确保Prometheus配置包含以下选择器: ```yaml serviceMonitorNamespaceSelector: {} # 允许发现所有ns的ServiceMonitor serviceMonitorSelector: {} # 选择所有ServiceMonitor ``` 如果Prometheus部署在独立命名空间(如monitoring),需额外配置RBAC 典型错误场景排查: ```shell # 检查ServiceMonitor是否被Prometheus识别 kubectl -n monitoring get prometheus -o yaml | grep serviceMonitor # 观察Target状态(应显示UP) kubectl port-forward svc/prometheus-operated -n monitoring 9090 # 浏览器访问 http://localhost:9090/targets 查看抓取状态 ``` 指标验证示例: ```promql # 控制平面指标 istiod_build{component="pilot"} # 网格内服务通信指标 istio_requests_total{reporter="destination"} ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值