### 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
Created
August 5, 2026 21:51
-
-
Save vorlon001/b147e7f5c26d63a14b0fe9e91e4bb8df to your computer and use it in GitHub Desktop.
Istio home labs
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment