Skip to content

Instantly share code, notes, and snippets.

@vorlon001
Created August 5, 2026 21:51
Show Gist options
  • Select an option

  • Save vorlon001/b147e7f5c26d63a14b0fe9e91e4bb8df to your computer and use it in GitHub Desktop.

Select an option

Save vorlon001/b147e7f5c26d63a14b0fe9e91e4bb8df to your computer and use it in GitHub Desktop.
Istio home labs
### Stage 1
### Init Service

kubectl apply -f - <<EOF
---
apiVersion: v1
kind: Namespace
metadata:
  name: echoserver
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoserver
  namespace: echoserver
spec:
  replicas: 5
  selector:
    matchLabels:
      app: echoserver
  template:
    metadata:
      labels:
        app: echoserver
    spec:
      containers:
      - image: harbor.iblog.pro/dockerio/ealen/echo-server:latest
        imagePullPolicy: IfNotPresent
        name: echoserver
        ports:
        - containerPort: 80
        env:
        - name: PORT
          value: "80"
---
apiVersion: v1
kind: Service
metadata:
  name: echoserver
  namespace: echoserver
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: ClusterIP
  selector:
    app: echoserver
EOF

kubectl  get all -n echoserver



kubectl apply -f - <<EOF
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned-issuer
  namespace: cert-manager
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: ca
  namespace: cert-manager
spec:
  isCA: true
  duration: 87600h # 10y
  subject:
    organizations:
      - "iBlog.pro"
    organizationalUnits:
      - "Kubernetes"
    localities:
      - "URAL"
    countries:
      - "RU"
  commonName: iblog.pro CA
  secretName: ca-secret
  privateKey:
    algorithm: RSA
    encoding: PKCS8
    size: 4096
  issuerRef:
    name: selfsigned-issuer
    kind: ClusterIssuer
    group: cert-manager.io
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: echoserver-issuer
  namespace: cert-manager
spec:
  ca:
    secretName: ca-secret
---
# Сертификат для всех нод echoserver
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: master-cert
  namespace: echoserver
spec:
  secretName: echoserver-tls
  duration: 8760h # 1y
  renewBefore: 360h # 15d
  commonName: istio.iblog.pro
  subject:
    organizations:
      - "iBlog.pro"
    organizationalUnits:
      - "Kubernetes"
    localities:
      - "URAL"
    countries:
      - "RU"
  isCA: false
  privateKey:
    algorithm: RSA
    encoding: PKCS8
    size: 4096
  dnsNames:
    - istio.iblog.pro
  issuerRef:
    group: cert-manager.io
    kind: ClusterIssuer
    name: echoserver-issuer
EOF

kubectl apply -f - <<EOF
---
# Сертификат для всех нод echoserver
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: master-cert
  namespace: istio-ingressgateway-system
spec:
  secretName: echoserver-tls
  duration: 8760h # 1y
  renewBefore: 360h # 15d
  commonName: istio.iblog.pro
  subject:
    organizations:
      - "iBlog.pro"
    organizationalUnits:
      - "Kubernetes"
    localities:
      - "URAL"
    countries:
      - "RU"
  isCA: false
  privateKey:
    algorithm: RSA
    encoding: PKCS8
    size: 4096
  dnsNames:
    - istio.iblog.pro
  issuerRef:
    group: cert-manager.io
    kind: ClusterIssuer
    name: echoserver-issuer
EOF

kubectl get ClusterIssuer,Certificate -A


### Stage 3
### Test Istio


kubectl apply -f - <<EOF
---
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: ingressgateway-echoserver
  namespace: istio-ingressgateway-system
spec:
  selector:
    istio: ingressgateway-system
  servers:
  - port:
      name: http
      number: 80
      protocol: HTTP
    hosts:
    - "istio.iblog.pro"
#    tls:
#      httpsRedirect: true
  - port:
      name: httpistio2
      number: 80
      protocol: HTTP
    hosts:
    - "istio2.iblog.pro"
#    tls:
#      httpsRedirect: true
  - port:
      name: https
      number: 443
      protocol: HTTPS
    hosts:
    - "istio.iblog.pro"
    tls:
      mode: SIMPLE
      minProtocolVersion: TLSV1_2
      cipherSuites:
      - ECDHE-ECDSA-AES128-GCM-SHA256
      - ECDHE-ECDSA-AES256-GCM-SHA384
      - ECDHE-ECDSA-CHACHA20-POLY1305
      - ECDHE-RSA-AES128-GCM-SHA256
      - ECDHE-RSA-AES256-GCM-SHA384
      - ECDHE-RSA-CHACHA20-POLY1305
      credentialName:  echoserver-tls
EOF
 
kubectl get gateway.networking.istio.io -A

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: echoserver
  namespace: echoserver
spec:
  gateways:
  - istio-ingressgateway-system/ingressgateway-echoserver
  hosts:
  - istio.iblog.pro
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: echoserver.echoserver.svc.cluster.local
        port:
          number: 80
EOF


kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: echoserver2
  namespace: echoserver
spec:
  gateways:
  - istio-ingressgateway-system/ingressgateway-echoserver
  hosts:
  - istio2.iblog.pro
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: echoserver.echoserver.svc.cluster.local
        port:
          number: 80
EOF
kubectl get VirtualService -A

ISTIOGW=`kubectl get svc -n istio-ingressgateway-system  | grep "12.0" | awk '{ print $4}'`
curl http://${ISTIOGW}   -v -H 'Host: istio.iblog.pro' && echo

apt install dnsutils -y

dig @10.97.128.10 echoserver.echoserver.svc.cluster.local
....
echoserver.echoserver.svc.cluster.local. 30 IN A 10.97.167.187


echo "12.0.100.91 istio.iblog.pro" >> /etc/hosts

curl -k https://istio.iblog.pro && echo

echo | openssl s_client -showcerts -servername istio.iblog.pro -connect 12.0.100.91:443 2>/dev/null | openssl x509 -inform pem -noout -text




kubectl apply -f - <<EOF
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: trace-filter
  namespace: istio-ingressgateway-system
spec:
  configPatches:
  - applyTo: HTTP_FILTER	
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
            subFilter:
              name: "envoy.filters.http.router"
    patch:
      operation: INSERT_BEFORE
      value:
        name: envoy.filters.http.lua
        typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
          default_source_code:
            inline_string: |
              function envoy_on_request(request_handle)
                -- Добавляем заголовок в запрос. 
                -- Метод add() добавит значение, даже если заголовок существует.
                request_handle:headers():add("X-Custom-Req-Trace-My", "gateway-processed")
                local headers = request_handle:headers()

                -- Получаем SSL информацию через Envoy Lua API
                local subject = ""
                local serial = ""
                local fingerprint = ""
                local valid_from = ""
                local expiration = ""
                local tls_version = ""
                local cipher = ""

                local ok, ssl = pcall(function()
                  return request_handle:connection():ssl()
                end)

                if ok and ssl then
                  -- TLS Version
                  local s1, v1 = pcall(function() return ssl:tlsVersion() end)
                  if s1 and v1 then tls_version = tostring(v1) end

                  -- Cipher Suite
                  local s2, v2 = pcall(function() return ssl:ciphersuiteString() end)
                  if s2 and v2 then cipher = tostring(v2) end

                  -- Subject Peer Certificate
                  local s3, v3 = pcall(function() return ssl:subjectPeerCertificate() end)
                  if s3 and v3 then subject = tostring(v3) end
                end

                -- Для serial, fingerprint, дат — используем StreamInfo properties
                local stream = request_handle:streamInfo()
                if stream then
                  local ps, vs = pcall(function() return stream:getProperty("downstream.peer_serial") end)
                  if ps and vs then serial = tostring(vs) end

                  local pf, vf = pcall(function() return stream:getProperty("downstream.peer_fingerprint") end)
                  if pf and vf then fingerprint = tostring(vf) end

                  local pvf, vvf = pcall(function() return stream:getProperty("downstream.peer_cert_not_before") end)
                  if pvf and vvf then valid_from = tostring(vvf) end

                  local pve, vve = pcall(function() return stream:getProperty("downstream.peer_cert_not_after") end)
                  if pve and vve then expiration = tostring(vve) end
                end

                -- Добавляем cert-info в заголовки запроса (передаются на NGINX-backend)
                headers:add("X-Client-DN", subject)
                headers:add("X-Client-Serial", serial)
                headers:add("X-Client-Fingerprint", fingerprint)
                headers:add("X-Client-Cert-NotBefore", valid_from)
                headers:add("X-Client-Cert-NotAfter", expiration)
                headers:add("X-TLS-Version", tls_version)
                headers:add("X-TLS-Cipher", cipher)
              end
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment