на основе centos7.9
,docker-ce-20.10.18
,kubelet-1.22.3-0
, traefik-2.9.10
Справочная документация: https://doc.traefik.io/traefik/routing/overview/.
В Traefik есть множество способов создания правил маршрутизации, например:
Ingress
Метод письмаIngressRoute
СпособGatewayAPI
из СпособПо сравнению с собственным методом записи Ingress, ingressRoute является новой функцией после версии 2.1. Проще говоря, они оба поддерживают маршрутизацию по пути (пути) и HTTP-маршрутизацию по имени домена (хоста), а также настройку HTTPS. Разница в том, что IngressRoute необходимо определить. расширение CRD, но оно поддерживает новые функции, такие как TCP, UDP-маршрутизация и промежуточное программное обеспечение, настоятельно рекомендуется использовать ingressRoute
правило | описывать |
---|---|
Headers(key, value) | Проверьте, есть ли в заголовках пара ключ-значение, ключ которой является ключом, а значение — значением. |
HeadersRegexp(key, regexp) | Проверьте, есть ли в заголовках пара ключ-значение, значение ключа которой соответствует регулярному выражению. |
Host(example.com, …) | Проверьте, содержится ли запрошенное доменное имя в определенном доменном имени. |
HostRegexp(example.com, {subdomain:[a-z]+}.example.com, …) | Проверьте, содержится ли запрошенное доменное имя в определенном доменном имени регулярного выражения. |
Method(GET, …) | Проверьте, входит ли метод запроса в число заданных методов (GET, POST, PUT, DELETE, PATCH). |
Path(/path, /articles/{cat:[a-z]+}/{id:[0-9]+}, …) | Соответствует определенному пути запроса, принимает ряд путей к литералам и регулярным выражениям. |
PathPrefix(/products/, /articles/{cat:[a-z]+}/{id:[0-9]+}) | Соответствует определенному пути префикса, он принимает диапазон путей к префиксам литералов и регулярных выражений. |
Query(foo=bar, bar=baz) | Соответствует параметрам строки запроса, принимая пары ключ-значение ключ=значение. |
ClientIP(10.0.0.0/16, ::1) | Соответствует, если IP-адрес запрашивающего клиента является одним из заданных IP/CIDR. Он принимает форматы IPv4, IPv6 и сегментов. |
В предыдущей главе о развертывании мы получили доступ к информационной панели traefik через nodePort и службу nodePort. Далее мы продемонстрируем три способа доступа к информационной панели через доменные имена.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-dashboard
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: ingress.traefik.local
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: traefik
port:
number: 9000
доступ: http://traefik.local
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: kube-system
spec:
entryPoints:
- web
routes:
- match: Host(`ingressroute.traefik.local`) && PathPrefix(`/`)
kind: Rule
services:
- name: traefik
port: 9000
Посетите: http://ingressroute.traefik.local.
В настоящее время Траефик верно Gateway APIs изреализоватьдана основе v1alpha1 Спецификация версии, последняя спецификация v1alpha2, поэтому могут быть некоторые отличия от последних спецификаций.
Создать класс шлюза
apiVersion: networking.x-k8s.io/v1alpha1
kind: GatewayClass
metadata:
name: traefik
spec:
controller: traefik.io/gateway-controller
создать шлюз
apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata:
name: http-gateway
namespace: kube-system
spec:
gatewayClassName: traefik
listeners:
- protocol: HTTP
port: 80
routes:
kind: HTTPRoute
namespaces:
from: All
selector:
matchLabels:
app: traefik
Создать httproute
apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
name: traefik-dashboard
namespace: kube-system
labels:
app: traefik
spec:
hostnames:
- "gateway.traefik.local"
rules:
- matches:
- path:
type: Prefix
value: /
forwardTo:
- serviceName: traefik
port: 9000
weight: 1
Посетите: http://gateway.traefik.local.
myapp1
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp1
spec:
selector:
matchLabels:
app: myapp1
template:
metadata:
labels:
app: myapp1
spec:
containers:
- name: myapp1
image: ikubernetes/myapp:v1
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: myapp1
spec:
type: ClusterIP
selector:
app: myapp1
ports:
- port: 80
targetPort: 80
myapp2
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp2
spec:
selector:
matchLabels:
app: myapp2
template:
metadata:
labels:
app: myapp2
spec:
containers:
- name: myapp2
image: ikubernetes/myapp:v2
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: myapp2
spec:
type: ClusterIP
selector:
app: myapp2
ports:
- port: 80
targetPort: 80
Создавайте ресурсы и получайте доступ к тестам
[root@k8s-node1 ~]# vim demo/app/myapp1.yml
[root@k8s-node1 ~]# vim demo/app/myapp2.yml
[root@k8s-node1 ~]# kubectl apply -f demo/app/
deployment.apps/myapp1 created
service/myapp1 created
deployment.apps/myapp2 created
service/myapp2 created
[root@k8s-node1 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d
myapp1 ClusterIP 10.100.229.135 <none> 80/TCP 33s
myapp2 ClusterIP 10.96.56.49 <none> 80/TCP 33s
[root@k8s-node1 ~]# curl 10.100.229.135
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-node1 ~]# curl 10.96.56.49
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
Для достижения цели: пользователи вне кластера получают доступ через http://myapp1.test.com имя домена, проксируйте запрос приложению myapp1.
Создать входной маршрут
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: myapp1
spec:
entryPoints:
- web # и configmap в определении из entrypoint То же имя
routes:
- match: Host(`myapp1.test.com`) # доменное имя
kind: Rule
services:
- name: myapp1 # имя svciz соответствует
port: 80 # иsvcизportпоследовательный
развертывать
[root@k8s-node1 ~]# vim demo/ingressroute/http-myapp1.yml
[root@k8s-node1 ~]# kubectl apply -f demo/ingressroute/http-myapp1.yml
ingressroute.traefik.containo.us/myapp1 created
тест доступа
самоподписанный сертификат
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=myapp2.test.com"
Создайте секрет типа tls
kubectl create secret tls myapp2-tls --cert=tls.crt --key=tls.key
Создать входной маршрут
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: myapp2
spec:
entryPoints:
- websecure # монитор websecure Эта точка входа — то место, где проходит да. 443 порт Приходитьдоступ routes:
- match: Host(`myapp2.test.com`)
kind: Rule
services:
- name: myapp2
port: 80
tls:
secretName: myapp2-tls # Назначенное имя tls
развертывать
[root@k8s-node1 ~]# vim demo/ingressroute/https-myapp2.yml
[root@k8s-node1 ~]# kubectl apply -f demo/ingressroute/https-myapp2.yml
ingressroute.traefik.containo.us/myapp2 created
тест доступа,потому чтодасамоподписанный сертификат, так что к подскажет, что это небезопасно
развертыватьmysql
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql
labels:
app: mysql
namespace: default
data:
my.cnf: |
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
skip-character-set-client-handshake = 1
default-storage-engine = INNODB
max_allowed_packet = 500M
explicit_defaults_for_timestamp = 1
long_query_time = 10
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mysql
name: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: abc123
ports:
- containerPort: 3306
volumeMounts:
- mountPath: /etc/mysql/conf.d/my.cnf
subPath: my.cnf
name: cm
volumes:
- name: cm
configMap:
name: mysql
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: default
spec:
ports:
- port: 3306
protocol: TCP
targetPort: 3306
selector:
app: mysql
ingressRouteTCP
SNI — это идентификатор имени службы, который TLS Расширения протокола. Поэтому только TLS маршрутизацияталантиспользовать Долженправилообозначениедоменное имя。非 TLS маршрутизация с использованием
*
изправило объявлять каждое не- TLS Запросы будут обрабатываться путем маршрутизации.
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: mysql
namespace: default
spec:
entryPoints:
- tcpep # 9200 порт
routes:
- match: HostSNI(`*`) # потому что Traefik 中использовать TCP маршрутизация Конфигурациянуждаться СНИ, в то время как SNI дазависимость TLS из, поэтому нам нужна Конфигурация Сертификат. Если Сертификат нет, мы можем киспользовать wildcard* (IP-адрес адаптации) для Конфигурации.
services:
- name: mysql
port: 3306
развертывать
[root@k8s-node1 ~]# vim demo/ingressrouteTCP/mysql.yml
[root@k8s-node1 ~]# kubectl apply -f demo/ingressrouteTCP/mysql.yml
configmap/mysql created
deployment.apps/mysql created
service/mysql created
[root@k8s-node1 ~]# vim demo/ingressrouteTCP/route.yml
[root@k8s-node1 ~]# kubectl apply -f demo/ingressrouteTCP/route.yml
ingressroutetcp.traefik.containo.us/mysql created
Проверка хоста вне кластера
Справочный адрес https://doc.traefik.io/traefik/routing/providers/kubernetes-crd/#kind-ingressroutetcp
В большинстве случаев маршрутизацию TCP не требуется настраивать с помощью TLS. Ниже показаны только два ключевых шага.
Создайте секрет типа tls
kubectl create secret tls redis-tls --key=redis.key --cert=redis.crt
Создать входной маршрутTCP,нуждаться携приносить secret
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: redis
spec:
entryPoints:
- redisep
routes:
- match: HostSNI(`redis.test.com`)
services:
- name: redis
port: 6379
tls:
secretName: redis-tls
создаватьприложение
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoamiudp
labels:
app: whoamiudp
spec:
replicas: 2
selector:
matchLabels:
app: whoamiudp
template:
metadata:
labels:
app: whoamiudp
spec:
containers:
- name: whoamiudp
image: traefik/whoamiudp:latest
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: whoamiudp
spec:
ports:
- port: 8080
protocol: UDP
selector:
app: whoamiudp
Настройка входного маршрутаUDP
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteUDP
metadata:
name: whoamiudp
spec:
entryPoints:
- udpep
routes:
- services:
- name: whoamiudp
port: 8080
Прямой доступ к проверке SVC
[root@k8s-node1 traefik]# kubectl get svc whoamiudp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
whoamiudp ClusterIP 10.96.119.116 <none> 8080/UDP 2m22s
[root@k8s-node1 traefik]# echo "WHO" | socat - udp4-datagram:10.96.119.116:8080
Hostname: whoamiudp-6ff7dd6fb9-8qfc7
IP: 127.0.0.1
IP: 10.244.169.174
[root@k8s-node1 traefik]# echo "test" | socat - udp4-datagram:10.96.119.116:8080
Received: test
доступ к проверке маршрута udp
[root@k8s-node1 traefik]# echo "WHO" | socat - udp4-datagram:k8s-node1:9300
Hostname: whoamiudp-6ff7dd6fb9-5l8rd
IP: 127.0.0.1
IP: 10.244.107.243
[root@k8s-node1 traefik]# echo "test" | socat - udp4-datagram:1.1.1.1:9300
Received: test
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: myapp1
spec:
entryPoints:
- web # и configmap в определении из entrypoint То же имя
routes:
- match: Host(`lb.test.com`) # доменное имя
kind: Rule
services:
- name: myapp1 # имя svciz соответствует
port: 80 # иsvcизportпоследовательный
- name: myapp2 # имя svciz соответствует
port: 80 # иsvcизportпоследовательный
развертывать
[root@k8s-node1 ~]# vim demo/lb/lb.yml
[root@k8s-node1 ~]# kubectl apply -f demo/lb/lb.yml
ingressroute.traefik.containo.us/myapp1 created
тест доступа, вы можете найти петлю, соответствующую myapp1 и myapp2 содержание
[root@k8s-node1 ~]# curl http://lb.test.com
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-node1 ~]# curl http://lb.test.com
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@k8s-node1 ~]# curl http://lb.test.com
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-node1 ~]# curl http://lb.test.com
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>