#kubernetes #reverse-proxy #iptables #istio
#kubernetes #обратный прокси #iptables #istio
Вопрос:
Предыстория:
Я пытаюсь использовать goreplay для зеркального отображения трафика в другое место назначения. Я обнаружил, что служба k8s — это балансировка нагрузки на уровне 4, из-за чего трафик не может быть перехвачен goreplay, поэтому я решаю добавить вспомогательный модуль обратного прокси внутри pod, как это делает istio.
Вот мой модуль yaml:
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
name: http
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
- image: nginx
imagePullPolicy: IfNotPresent
name: proxy
resources:
limits:
cpu: "2"
memory: 1Gi
requests:
cpu: 10m
memory: 40Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /etc/nginx/conf.d
name: default
initContainers:
- command:
- iptables
args:
- -t
- nat
- -A
- PREROUTING
- -p
- tcp
- --dport
- "80"
- -j
- REDIRECT
- --to-ports
- "15001"
image: soarinferret/iptablesproxy
imagePullPolicy: IfNotPresent
name: istio-init
resources:
limits:
cpu: 100m
memory: 50Mi
requests:
cpu: 10m
memory: 10Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_ADMIN
- NET_RAW
drop:
- ALL
privileged: false
readOnlyRootFilesystem: false
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
terminationGracePeriodSeconds: 30
volumes:
- configMap:
defaultMode: 256
name: default
optional: false
name: default
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
---
apiVersion: v1
data:
default.conf: |
server {
listen 15001;
server_name localhost;
access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
kind: ConfigMap
metadata:
name: default
namespace: default
Я использую, kubectl port-forward service/nginx 8080:80
а затем curl http://localhost:8080
трафик был отправлен непосредственно на nginx, а не на мой прокси.
ЧЕГО я ХОЧУ:
- Способ позволить goreplay захватывать трафик, который балансируется службой k8s.
- Исправьте правило iptables, чтобы трафик успешно направлялся на мой прокси-сервер.
Спасибо за любую помощь!
Комментарии:
1. просто отправьте порт трафика 15001 в определении вашего сервиса.
2. Не могли бы вы попробовать с
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 80 -j REDIRECT --to-port 15001
? Кроме того, я бы посоветовал ознакомиться с этим руководством по этому поводу, не совсем по nginx, но объясняет, как на самом деле создать прокси.3. Если вы скопировали часть контейнера инициализации из istio:
15001
для исходящего трафика,15006
для входящего трафика. Входящая часть отсутствует.4. @Jakub Большое спасибо за ваш ответ, после того, как я поработал с руководством, которое вы даете, я обнаружил, что перенаправление портов отличается от обычного вызова службы k8s. После того, как я изменил привилегированное значение на ture в поле SecurityContext initConatiner, все работает хорошо.
5. @Jonyhy96 Конечно, рад, что это работает для вас! Я добавил ответ для большей наглядности. Если бы это помогло рассмотреть возможность голосования / принятия ответа.
Ответ №1:
Как упоминал @Jonyhy96 в комментариях, единственное, что здесь нужно изменить, — это присвоить привилегированному значению значение true в SecurityContext поле initContainer.
Привилегированный — определяет, может ли какой-либо контейнер в модуле включать привилегированный режим. По умолчанию контейнеру не разрешен доступ к каким-либо устройствам на хосте, но «привилегированному» контейнеру предоставляется доступ ко всем устройствам на хосте. Это обеспечивает контейнеру почти тот же доступ, что и процессам, запущенным на хосте. Это полезно для контейнеров, которые хотят использовать возможности Linux, такие как управление сетевым стеком и доступ к устройствам.
Таким образом, initContainer будет выглядеть следующим образом
initContainers:
- command:
- iptables
args:
- -t
- nat
- -A
- PREROUTING
- -p
- tcp
- --dport
- "80"
- -j
- REDIRECT
- --to-ports
- "15001"
image: soarinferret/iptablesproxy
imagePullPolicy: IfNotPresent
name: istio-init
resources:
limits:
cpu: 100m
memory: 50Mi
requests:
cpu: 10m
memory: 10Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_ADMIN
- NET_RAW
drop:
- ALL
privileged: true <---- changed from false
readOnlyRootFilesystem: false
runAsGroup: 0
runAsNonRoot: false
runAsUser: 0
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
Об этом есть очень хороший учебник, не совсем по nginx, но объясняет, как на самом деле создать прокси.
Ответ №2:
Приведенный выше SecurityContext работает, за исключением требования изменения для разрешения расширения привилегий: true
Следующая урезанная версия также работает на GKE (движок Google Kubernetes):
securityContext:
capabilities:
add:
- NET_ADMIN
drop:
- ALL
privileged: true