Istio 札记杂录

黑白名单ACL

针对某个目录做ACL,如 /login 只限指定的白名单访问,其它一律禁止访问。

实现步骤

1、确保istio接收的IP是用户地址
<略>

2、创建AuthorizationPolicy资源

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: ingress-policy
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: istio-ingressgateway
  action: DENY
  rules:
    - from:
       - source:
           notIpBlocks: ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16" ]
           #ipBlocks: ["192.168.0.0/24"]
      to:
       - operation:
           hosts:
           - demo.vqiu.cn
           paths: 
           - /login/*

测试结果

$ curl http://demo.vqiu.cn/login -I
HTTP/1.1 403 Forbidden
content-length: 19
content-type: text/plain
date: Fri, 08 May 2023 06:16:20 GMT
server: istio-envoy

参考链接:

Istio ingress 配置SSL证书

方法1 使用证书名称引入

删除已存在的证书

# kubectl --ignore-not-found=true -n istio-system delete secret ingressgateway-credential

创建新证书

# kubectl create -n istio-system secret tls ingressgateway-credential \
                                            --key=private.pem \
                                            --cert=fullchain.crt

在Gateway中引入证书

# cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ingress-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "demo.vqiu.cn"
    tls:
      httpsRedirect: true 
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: ingressgateway-credential
    hosts:
    - "ssl.vqiu.vqiu"
EOF

提示:credentialName的名称必须与前面创建的secure名称一致。

方法2 使用证书路径引入

删除已存在ingressgateway-credential

# kubectl --ignore-not-found=true -n istio-system delete secret ingressgateway-credential

创建新证书资源

kubectl create secret tls istio-ingressgateway-certs -n istio-system \
                          --key private.pem \
                          --cert fullchain.crt \

Secret的名称必须以istio开头

创建或更新istio ingress

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ingress-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "demo.vqiu.cn"
    tls:
      httpsRedirect: true 
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
      privateKey: /etc/istio/ingressgateway-certs/tls.key
    hosts:
    - "ssl.vqiu.vqiu"
EOF

Metrics监控

  • 版本:1.6.5

一、将Istio的Metrics暴露出来

istio-ingressgateway 默认没有将Metrics接口暴露出来,可以使用以下2种方法将istio的Metrics接口暴露出来:

方法1:在原有service资源新增metrics

操作如下:

# kubectl -n istio-system edit svc istio-ingressgateway
<省略若干行>
spec:
  ports:
  - name: http-envoy-prom
    port: 15090
    protocol: TCP
    targetPort: http-envoy-prom
<省略若干行>

方法2: 单独创建一个metrics Service资源

apiVersion: v1
kind: Service
metadata:
  labels:
    app: istio-ingressgateway
    istio: ingressgateway
    operator.istio.io/component: IngressGateways
    operator.istio.io/managed: Reconcile
    operator.istio.io/version: 1.6.5
    release: istio
  name: istio-ingressgateway-prometheus
  namespace: istio-system
spec:
  ports:
  - name: http-envoy-prom
    port: 15090
    protocol: TCP
    targetPort: http-envoy-prom
  selector:
    app: istio-ingressgateway
    istio: ingressgateway
  sessionAffinity: None
  type: ClusterIP

完成后可以使用以下方式测试Metrics是否正常:

# curl $SERVICE_IP:15090/stats/prometheus

二、创建ServiceMonitor资源

apiVersion: v1
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: istio-ingressgateway-servicemonitor
  namespace: istio-system
spec:
  endpoints:
  - path: /stats/prometheus
    port: http-envoy-prom
  namespaceSelector:
    matchNames:
    - istio-system
  selector:
    matchLabels:
      app: istio-ingressgateway
      istio: ingressgateway

完成上述2步,Grafana就可以正常查看到Istio的监控资源。

Rewrite重写示例

k8s 集群中部署一个minio,对外服务目录为s3

http://s3.vqiu.local/s3/ -> minio:9000/minio

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: minio-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - s3.vqiu.local
    port:
      name: http
      number: 80
      protocol: HTTP
        
---

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: minio-vs
spec:
  gateways:
  - minio-gateway
  hosts:
  - '*'
  http:
  - match:
    - uri:
        prefix: /s3
    rewrite:
      uri: /minio
    route:
    - destination:
        host: minio.default.svc.cluster.local
        port:
          number: 9000

代理外部服务

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: vqiu-cn
spec:
  hosts:
  - vqiu.local
  location: MESH_EXTERNAL
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: STATIC
  endpoints:
  - address: 125.xx.xx.xxx
EOF


kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: gitee-qiu
spec:
  gateways:
  - gitee-gateway
  hosts:
  - '*'
  http:
  - match:
    - uri:
        prefix: /qiuqiu
    route:
    - destination:
        host: vqiu.local
        port:
          number: 80
EOF

参考引用:

开启istio 日志

环境

  • 版本:1.6.5
  • Kubernetes: v1.18.3

操作

Istio的日志配置在一叫istio的configmap资源中,新增以下配置:

# kubectl edit configmap istio -n istio-system
apiVersion: v1
data:
  mesh: |-
    <省略若干行>
    # Set accessLogFile to empty string to disable access log.
    accessLogFile: "/dev/stdout"
    
    # Set accessLogEncoding to JSON or TEXT to configure sidecar access log
    accessLogEncoding: 'TEXT'
    <省略若干行>

重启istio

kubectl rollout restart deployment istio-ingressgateway -n istio-system

查看日志

kubectl logs istio-ingressgateway-ilf35135539-xxxxx -n istio-system -f

参考引用

ARM平台部署

  • Isiot版本: 1.10.3

初始化operator

 istioctl operator init --hub=docker.io/querycapistio --tag=1.10.3

部署

# kubectl apply -f - <<EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  namespace: istio-system
  name: example-istiocontrolplane
spec:
  hub: docker.io/querycapistio
  profile: default
  components:
    pilot:
      k8s: # each components have to set this
        affinity: &affinity
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              nodeSelectorTerms:
                - matchExpressions:
                    - key: kubernetes.io/arch
                      operator: In
                      values:
                        - arm64
                        - amd64
    egressGateways:
      - name: "istio-egressgateway"
        k8s:
          affinity: *affinity
    ingressGateways:
      - name: "istio-ingressgateway"
        k8s:
          affinity: *affinity
EOF

应用测试

  • gateway
 kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ingress-gateway
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
EOF
  • 创建 vs
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demo
spec:
  hosts:
  - "*"
  gateways:
  - httpbin-gateway
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        port:
          number: 8000
        host: nginx
EOF

部署demo应用

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  selector:
    matchLabels:
      app: nginx-deploy
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      containers:
      - name: nginx-deploy
        image: nginx:stable-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          protocol: TCP
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /
            port: 80
            scheme: HTTP
          initialDelaySeconds: 20
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        readinessProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
---
kind: Service
apiVersion: v1
metadata:
  name: nginx
spec:
  selector:
    app: nginx-deploy
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80

curl 测试

# curl  http://localhost:32719 -I
HTTP/1.1 200 OK
server: istio-envoy
date: Wed, 24 Nov 2021 09:53:41 GMT
content-type: text/html
content-length: 612
last-modified: Tue, 16 Nov 2021 15:03:58 GMT
etag: "6193c85e-264"
accept-ranges: bytes
x-envoy-upstream-service-time: 0

开启Gzip

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: ingressgateway-gzip
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: GATEWAY
        listener:
          filterChain:
            filter:
              name: "envoy.http_connection_manager"
              subFilter:
                name: 'envoy.router'
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.gzip
          config:
            remove_accept_encoding_header: true
            compression_level: DEFAULT