Es war einmal, da hatten wir ein Problem mit einem Kubernetes Cluster. Es dauerte einige Tage, das Problem zu lösen und die Benutzer erfuhren eine Diensteeinschränkung für eine ungewöhnlich lange Zeit. Das war der Startpunkt, um über Cluster-Redundanz und Service Mesh nachzudenken.
Ein Service Mesh beschreibt eine Funktionalität, um Dienste in verschiedenen Versionen oder Lokationen zu mischen. Istio ist ein solcher Service Mesh, welchen wir untersuchen möchten, um folgende Probleme zu lösen:
Hinweis: Es gibt bislang schon technische Lösungen, um diese Probleme mit Kubernetes Werkzeugen und ohne Service Mesh zu lösen, da man sich eine Menge technische Abhängigkeiten einlädt.
Los gehts!
Die Cluster erfüllen voll den CIS Benchmark Check
restricted
PodSecurityPolicy ist erzwungencurl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
$ curl -L https://istio.io/downloadIstio | sh -
Wir werden den Istio Operator benutzen, um jeden Schritt der Installation von Istio Version 1.12.0 (ältere Versionen haben Probleme bei der Verbindung von Multi-Clustern)
Projektziel ist die Installation des Istio Helloworld Beispiels in beiden Clustern und verteilen der Traffic. Das Zielbild sieht so aus:
Annahmen:
No | Name | ID | Network | Mesh |
---|---|---|---|---|
1 | mcsps-test-k8s-01 | c-f7r9g | mcsps-test-01 | mcsps-test |
2 | mcsps-test-k8s-02 | c-pzk8b | mcsps-test-02 | mcsps-test |
Erstelle ein Projekt istio
fuer beide Cluster im Rancher Kontext:
$ cat <<EOF | kubectl -n c-f7r9g apply -f -
apiVersion: management.cattle.io/v3
kind: Project
metadata:
name: istio
spec:
clusterName: c-f7r9g
containerDefaultResourceLimit:
limitsCpu: 200m
limitsMemory: 128Mi
requestsCpu: 100m
requestsMemory: 64Mi
description: Istio Manage Project
displayName: istio
enableProjectMonitoring: false
namespaceDefaultResourceQuota:
limit:
limitsCpu: "12000m"
limitsMemory: "12000Mi"
resourceQuota:
limit:
limitsCpu: "12000m"
limitsMemory: "12000Mi"
EOF
Erstelle einen Namespace istio-system
fuer beide Cluster im Cluster Kontext:
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
annotations:
field.cattle.io/projectId: c-pzk8b:istio
field.cattle.io/resourceQuota: '{"limit":{"limitsCpu":"12000m","limitsMemory":"12000Mi"}}'
lifecycle.cattle.io/create.namespace-auth: "true"
scheduler.alpha.kubernetes.io/node-selector: role=ingress
labels:
field.cattle.io/projectId: istio
topology.istio.io/network: mcsps-test-01
name: istio-system
EOF
ingress
haben.
Ansonsten kann man die Annotation loeschen.Erstelle LimitRange in istio-system
Namespace fuer Container Default Quota:
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: LimitRange
metadata:
labels:
resourcequota.management.cattle.io/default-resource-quota: "true"
name: istio-limitrange
namespace: istio-system
spec:
limits:
- default:
cpu: 100m
memory: 100Mi
defaultRequest:
cpu: 10m
memory: 10Mi
type: Container
EOF
Erstelle einen Namespace sample
in beiden Clustern in Cluster Kontext:
$ kubectl create namespace sample
$ kubectl label namespace sample istio-injection=enabled --overwrite
$ istioctl operator init --tag 1.12.0 --hub mtr.external.otc.telekomcloud.com/istio
Dadurch wird der Istio Operator im Namespace istio-operator
erstellt
In der Istio Documentation sind einige Aufgaben erwaehnt wie Configure Trust
. Dafuer gibt es auch ein Beispiel
Im sample/certs Verzeichnis:
$ make -f ../tools/certs/Makefile.selfsigned.mk root-ca
$ make -f ../tools/certs/Makefile.selfsigned.mk mcsps-test-k8s-01-cacerts
$ make -f ../tools/certs/Makefile.selfsigned.mk mcsps-test-k8s-02-cacerts
Auf dem Cluster anwenden (mit Kontext cluster 01):
$ ./mcsps-test-k8s-01.sh
Auf dem Cluster anwenden (mit Kontext cluster 02):
$ ./mcsps-test-k8s-02.sh
Erstellte Secrets überprüfen
$ kubectl -n istio-system get secrets cacerts
cacerts Opaque 4 57d
Erstellen eines Rancher Token mit Skope auf cluster1 und cluster2, erstellen einer kube-config
Datei wie in diesem Beispiel und kodieren mit base64
$ cat <<EOF | base64 -w0
apiVersion: v1
clusters:
- cluster:
server: https://raseed-test.external.otc.telekomcloud.com:443/k8s/clusters/c-f7r9g
name: mcsps-test-k8s-01
contexts:
- context:
cluster: mcsps-test-k8s-01
user: mcsps-test-k8s-01
name: mcsps-test-k8s-01
current-context: mcsps-test-k8s-01
kind: Config
preferences: {}
users:
- name: mcsps-test-k8s-01
user:
token: token-hfjvg:tsjn2k5vlvjjzqhwpbpzwfkb549q54pdxrksfn6hw82svbq5vcgrml
EOF
Erstellen eines Remote Secret mit bas64 mit diesen Credentials und dem Namen des anderen Clusters,
$ cat <<EOF | kubectl -n istio-system apply -f -
apiVersion: v1
data:
mcsps-test-k8s-01: YXBpVmVyc2lvbjogdjEKY2x1c3RlcnM6Ci0gY2x1c3RlcjoKICAgIHNlcnZlcjogaHR0cHM6Ly9yYXNlZWQtdGVzdC5leHRlcm5hbC5vdGMudGVsZWtvbWNsb3VkLmNvbS9rOHMvY2x1c3RlcnMvYy1mN3I5ZwogIG5hbWU6IG1jc3BzLXRlc3QtazhzLTAxCmNvbnRleHRzOgotIGNvbnRleHQ6CiAgICBjbHVzdGVyOiBtY3Nwcy10ZXN0LWs4cy0wMQogICAgdXNlcjogbWNzcHMtdGVzdC1rOHMtMDEKICBuYW1lOiBtY3Nwcy10ZXN0LWs4cy0wMQpjdXJyZW50LWNvbnRleHQ6IG1jc3BzLXRlc3QtazhzLTAxCmtpbmQ6IENvbmZpZwpwcmVmZXJlbmNlczoge30KdXNlcnM6Ci0gbmFtZTogbWNzcHMtdGVzdC1rOHMtMDEKICB1c2VyOgogICAgdG9rZW46IHRva2VuLWhmanZnOnRzam4yazV2bHZqanpxaHdwYnB6d2ZrYjU0OXE1NHBkeHJrc2ZuNmh3ODJzdmJxNXZjZ3JtbAo=
kind: Secret
metadata:
annotations:
networking.istio.io/cluster: mcsps-test-k8s-01
labels:
istio/multiCluster: "true"
name: istio-remote-secret-mcsps-test-k8s-01
namespace: istio-system
type: Opaque
EOF
Überprüfen des Remote Secret in jedem Cluster:
$ kubectl -n istio-system get secrets | grep remote-secret
istio-remote-secret-mcsps-test-k8s-01 Opaque 1 57d
Hinweis: Es gibt noch einen anderen Weg, um die Remote Secret mit Zertifikaten zu erstellen, aber es wird hier nur erwähnt:
$ istioctl x create-remote-secret \
--name=mcsps-test-k8s-01 --context=mcsps-test-k8s-01
Jetzt werden wir den Istio Controllplane in jedem Cluster installieren:
$ cat <<EOF | kubectl -n istio-system apply -f -
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: mcsps-test
namespace: istio-system
spec:
tag: 1.12.0
profile: demo
hub: mtr.external.otc.telekomcloud.com/istio
values:
global:
meshID: mcsps-test
multiCluster:
clusterName: mcsps-test-k8s-01
enabled: true
network: mcsps-test-01
EOF
Installation Easwestgateway in jedem Cluster:
$ cat <<EOF | kubectl -n istio-system apply -f -
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: eastwest
spec:
tag: 1.12.0
hub: mtr.external.otc.telekomcloud.com/istio
revision: ""
profile: empty
components:
ingressGateways:
- name: istio-eastwestgateway
label:
istio: eastwestgateway
app: istio-eastwestgateway
topology.istio.io/network: mcsps-test-01
enabled: true
k8s:
env:
- name: ISTIO_META_REQUESTED_NETWORK_VIEW
value: mcsps-test-01
service:
ports:
- name: status-port
port: 15021
targetPort: 15021
- name: tls
port: 15443
targetPort: 15443
- name: tls-istiod
port: 15012
targetPort: 15012
- name: tls-webhook
port: 15017
targetPort: 15017
values:
gateways:
istio-ingressgateway:
injectionTemplate: gateway
global:
network: mcsps-test-01
EOF
Exponieren mTLS Service in jedem Cluster:
$ cat <<EOF | kubectl -n istio-system apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: cross-network-gateway
spec:
selector:
istio: eastwestgateway
servers:
- port:
number: 15443
name: tls
protocol: TLS
tls:
mode: AUTO_PASSTHROUGH
hosts:
- "*.local"
EOF
$ kubectl -n istio-system get all
NAME READY STATUS RESTARTS AGE
pod/istio-eastwestgateway-75584d6b7d-qpnn2 1/1 Running 0 22h
pod/istio-egressgateway-74844b98b7-k4bp9 1/1 Running 0 22h
pod/istio-ingressgateway-88854fd9d-c2kbm 1/1 Running 0 22h
pod/istiod-55f8ddf47f-hgvps 1/1 Running 0 22h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
AGE
service/istio-eastwestgateway LoadBalancer 10.43.237.208 80.158.38.107 15021:31548/TCP,15443:31645/TCP,15012:31299/TCP,15017:32553/TCP 22h
service/istio-egressgateway ClusterIP 10.43.123.134 <none> 80/TCP,443/TCP
22h
service/istio-ingressgateway LoadBalancer 10.43.234.25 80.158.47.22 15021:32029/TCP,80:30040/TCP,443:30229/TCP,31400:32720/TCP,15443:30421/TCP 22h
service/istiod ClusterIP 10.43.139.98 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP
22h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/istio-eastwestgateway 1/1 1 1 22h
deployment.apps/istio-egressgateway 1/1 1 1 22h
deployment.apps/istio-ingressgateway 1/1 1 1 22h
deployment.apps/istiod 1/1 1 1 22h
NAME DESIRED CURRENT READY AGE
replicaset.apps/istio-eastwestgateway-75584d6b7d 1 1 1 22h
replicaset.apps/istio-egressgateway-74844b98b7 1 1 1 22h
replicaset.apps/istio-egressgateway-f994cbcf8 0 0 0 22h
replicaset.apps/istio-ingressgateway-88854fd9d 1 1 1 22h
replicaset.apps/istiod-55f8ddf47f 1 1 1 22h
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/istio-eastwestgateway Deployment/istio-eastwestgateway 18%/80% 1 5 1 22h
Wenn istiod nicht startet wegen Cluster Zugriffsproblemen muss die CluserRole angepasst werden:
Behoben in Istio 1.12.0
$ kubectl edit clusterrole istiod-istio-system
# verify/add
- apiGroups:
- extensions.istio.io
resources:
- wasmplugins
verbs:
- get
- watch
- list
$ kubectl -n istio-system get istiooperators.install.istio.io
NAME REVISION STATUS AGE
eastwest HEALTHY 22h
mcsps-test HEALTHY 22h
$ kubectl -n istio-system get gateways.networking.istio.io
NAME AGE
cross-network-gateway 22h
Hinweis: Die originalen Beispiele befinden sich im Istio Github Repo
cluster1:
deploy v1
$ kubectl -n sample apply -f https://raw.githubusercontent.com/mcsps/use-cases/master/istio/helloworld.yaml -l version=v1
$ kubectl -n sample apply -f https://raw.githubusercontent.com/mcsps/use-cases/master/istio/helloworld.yaml -l service=helloworld
$ kubectl -n sample apply -f https://raw.githubusercontent.com/mcsps/use-cases/master/istio/helloworld-gateway.yaml
cluster2:
deploy v2
$ kubectl -n sample apply -f https://raw.githubusercontent.com/mcsps/use-cases/master/istio/helloworld.yaml -l version=v2
$ kubectl -n sample apply -f https://raw.githubusercontent.com/mcsps/use-cases/master/istio/helloworld.yaml -l service=helloworld
$ kubectl -n sample apply -f https://raw.githubusercontent.com/mcsps/use-cases/master/istio/helloworld-gateway.yaml
Istio und Rancher haben schon ein paar NetworkPolicy Regeln installiert:
$ kubectl -n sample get networkpolicies.networking.k8s.io
NAME POD-SELECTOR AGE
hn-nodes <none> 32h
np-default <none> 32h
$ kubectl -n istio-system get networkpolicies.networking.k8s.io
NAME POD-SELECTOR AGE
hn-nodes <none> 29h
np-default <none> 29h
np-istio-eastwestgateway app=istio-eastwestgateway,istio=eastwestgateway,topology.istio.io/network=mcsps-test-01 29h
np-istio-ingressgateway app=istio-ingressgateway,istio=ingressgateway 29h
Rancher Standardregeln sind gut für “normale” Kommunikation über Overlay Network oder Ingress im selben Cluster.
Für die Helloworld App haben wir die erlaubte Kommunikation in beiden Clustern zu definieren:
Diese Regel sollte alle Traffic von und zu Namespaces erlauben, bei denen istio-injection
gesetzt ist:
$ cat <<EOF | kubectl -n istio-system apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: np-istio
spec:
egress:
- to:
- namespaceSelector:
matchLabels:
istio-injection: enabled
ingress:
- from:
- namespaceSelector:
matchLabels:
istio-injection: enabled
podSelector: {}
policyTypes:
- Egress
- Ingress
EOF
Mit dieser Regel erlauben wir explizit Traffic von und zu Istio Service Ports, Kube-API und Kube-DNS:
$ cat <<EOF | kubectl -n istio-system apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
annotations:
name: np-istio-ports
namespace: istio-system
spec:
egress:
- ports:
- port: 15010
protocol: TCP
- ports:
- port: 15012
protocol: TCP
- ports:
- port: 15014
protocol: TCP
- ports:
- port: 15017
protocol: TCP
- ports:
- port: 15443
protocol: TCP
- ports:
- port: 6443
protocol: TCP
- ports:
- port: 80
protocol: TCP
- ports:
- port: 53
protocol: TCP
- ports:
- port: 53
protocol: UDP
ingress:
- ports:
- port: 80
protocol: TCP
- ports:
- port: 15010
protocol: TCP
- ports:
- port: 15012
protocol: TCP
- ports:
- port: 15014
protocol: TCP
- ports:
- port: 15017
protocol: TCP
- ports:
- port: 15443
protocol: TCP
podSelector: {}
policyTypes:
- Egress
- Ingress
EOF
Am Ende erlauben wir in unserer App auch Traffic zu Istio Service, Kube-DNS und natürlich dem Service Port, auf dem Helloworld ausgeliefert wird:
$ cat <<EOF | kubectl -n sample apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
annotations:
name: np-helloworld
spec:
egress:
- ports:
- port: 5000
protocol: TCP
- ports:
- port: 15012
protocol: TCP
- ports:
- port: 53
protocol: UDP
ingress:
- ports:
- port: 5000
protocol: TCP
- ports:
- port: 15012
protocol: TCP
podSelector:
matchLabels:
app: helloworld
policyTypes:
- Egress
- Ingress
EOF
Überprüfen Eastwest Traffic
$ istioctl -n sample proxy-config endpoint helloworld-v2-5866f57dd6-8hgml| grep helloworld
10.42.6.65:5000 HEALTHY OK outbound|5000|v2|helloworld.sample.svc.cluster.local
10.42.6.65:5000 HEALTHY OK outbound|5000||helloworld.sample.svc.cluster.local
80.158.16.72:15443 HEALTHY OK outbound|5000|v1|helloworld.sample.svc.cluster.local
80.158.16.72:15443 HEALTHY OK outbound|5000||helloworld.sample.svc.cluster.local
Bei funktionierendem Eastwest Gateway sollten wir als Endpunkt die Loadbalancer Ip-Adresse des Remote Cluster auf dem mTLS port 15443 sehen. Ohne Eastwest erscheint die POD-IP jedes Helloworld POD (welche im Remote Cluster nicht erreichbar ist).
$ for i in {1..12}; do curl http://80.158.47.22/hello;sleep 1;done
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Das Istio Project sammelte Informationen in einem Leitfaden zur Fehlersuche.
Um etwas Ordnung im Trafficmanagement der Helloworld zu bekommen, entscheiden wir welche Version auf welchem Endpunkt läuft:
$ cat <<EOF | kubectl -n sample apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: helloworld
spec:
host: helloworld
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
Jetzt können wir sagen, 90% der Traffic wird von einem Service ausgeliefert und 10% vom anderen:
$ cat <<EOF | kubectl -n sample apply -f -
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: helloworld
spec:
gateways:
- helloworld-gateway
hosts:
- '*'
http:
- match:
- uri:
exact: /hello
route:
- destination:
host: helloworld
port:
number: 5000
subset: v1
weight: 10
- destination:
host: helloworld
port:
number: 5000
subset: v2
weight: 90
EOF
Nicht zu vergessen ist, dies auf beide Cluster anzuwenden, um beide Ingress mit derselben Konfiguration zu versorgen. Jetzt sollten wir mehr v2 Versionen in der Antwortschleife sehen:
$ for i in {1..12}; do curl http://80.158.47.22/hello;sleep 1;done
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Um mehr produktionsreif zu sein, wir möchten SSL-Terminierung am Frontend verwenden, eine selbstverwaltetes Let’s Encrypt Zertifikat zusammen mit einem üblichen Hostnamen.
Um mit dem Hostname Problem zu beginnen, verwenden wir schon External-DNS](https://github.com/kubernetes-sigs/external-dns) und müssen die Quellenliste erweitern, wo external-dns auf Annotations hört:
- args:
- --log-level=info
- --log-format=text
- --domain-filter=mcsps.telekomcloud.com
- --policy=sync
- --provider=designate
- --registry=txt
- --interval=1m
- --txt-owner-id=$(K8S_NAME)
- --txt-prefix=_$(K8S_NAME)_
- --source=service
- --source=ingress
- --source=istio-gateway
Weiterhin gibt es beim cert-manager ein Problem mit Istio,
weswegen er nicht im User Namespace arbeiten kann, in dem
sich die Applikation befindet (sample
).
“The Certificate should be created in the same namespace as the istio-ingressgateway”
Ref: https://istio.io/latest/docs/ops/integrations/certmanager/
Das mag die Entscheidung sein, dass der Cluster Admin verantwortlich ist für diese Aufgabe und nicht der User ohne Berechtigung im Istio Projekt in Rancher.
Erstellen eines Gateway für SSL Terminierung
$ cat <<EOF | kubectl -n istio-system apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
annotations:
external-dns.alpha.kubernetes.io/target: 80.158.47.22
name: helloworld-ssl-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: helloistio-mcsps-telekomcloud-com
hosts:
- helloistio.mcsps.telekomcloud.com
EOF
Das DNS Ziel ist die IP-Adresse des IngressGateway Hinweis: Um mit dem external-dns Webhool zu kommunizieren, benötigen wir eine NetworkPolicy Egress tcp/80 Regel.
Erstellen des VirtualService für Traffic Routing zur Helloworld App im sample Namespace:
$ cat <<EOF | kubectl -n istio-system apply -f -
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
name: helloworld-ssl
spec:
gateways:
- helloworld-ssl-gateway
hosts:
- '*'
http:
- match:
- uri:
exact: /hello
route:
- destination:
host: helloworld.sample.svc.cluster.local
port:
number: 5000
subset: v1
weight: 90
- destination:
host: helloworld.sample.svc.cluster.local
port:
number: 5000
subset: v2
weight: 10
EOF
Erstellen eines Zertifikats für Helloworld:
$ cat <<EOF | kubectl -n istio-system apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: helloistio
spec:
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: letsencrypt-wild
secretName: helloistio-mcsps-telekomcloud-com
commonName: helloistio.mcsps.telekomcloud.com
dnsNames:
- helloistio.mcsps.telekomcloud.com
EOF
Da ist die Annahme, wir haben einen ClusterIssuer letsencrypt-wild
mit
dns01-challenge und eine Designate-verwaltete Domain, da wir external-dns benutzen.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-wild
spec:
acme:
email: cloud-operations@telekom.de
preferredChain: ""
privateKeySecretRef:
name: letsencrypt-wild
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- dns01:
webhook:
groupName: acme.syseleven.de
solverName: designatedns
Let`s Encrypt http-01 Challenge wird nicht aus dem Hut mit Istio funktionieren, da die Challenge eine temporaere Ingress Defintion erwartet.
Man wird sowas wie dies hier auf dem IngressGateway sehen:
[2021-12-11T17:40:54.432Z] "GET /.well-known/acme-challenge/Q14PwTatb9y3RPS3o4jss2NQL5lioZTnevB4kI7lns44 HTTP/1.1" 404 NR route_not_found - "-" 0 0 0 - "10.42.7.0" "cert-manager/v1.5.3 (clean)" "4828cac7-ae2d-91e7-9699-a6c2e9a82321" "helloistio.mcsps.telekomcloud.com" "-" - - 10.42.6.79:8080 10.42.7.0:13840 - -
Überprüfen ob das Zertifikat ausgestellt wurde:
$ kubectl -n istio-system get certificate
NAME READY SECRET AGE
helloistio True helloistio-mcsps-telekomcloud-com 56m
Verbindung überprüfen:
$ for i in {1..12}; do curl https://helloistio.mcsps.telekomcloud.com/hello;sleep 1;done
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v2, instance: helloworld-v2-5866f57dd6-8hgml
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Hello version: v1, instance: helloworld-v1-c6c4969d7-lfgw7
Dieselbe Aufgabe ist auf dem zweiten Cluster erforderlich, um wirklich autonom zu sein. Unerfreulicherweise wir können keine mehrfache A Records von verschiedenen Instanzen in external-dns setzen. So müssen wir diese Automatisierungsschritt überspringen und können 2 A-Records manuell setzen:
$ host helloistio.mcsps.telekomcloud.com
helloistio.mcsps.telekomcloud.com has address 80.158.54.11
helloistio.mcsps.telekomcloud.com has address 80.158.59.119
Der Schleifentest oben sollte an beiden Endpunkten funktionieren und sollte entsprechend der Namensauflösung folgen.
Mehr Beispiele gibt es im Istio Github Repo oder Istio Dokumentation.
Viel Spass mit Istio!