Трафік TCP
Це завдання показує, як налаштувати політику авторизації Istio для TCP-трафіку в Istio mesh.
Перед початком
Перед початком цього завдання виконайте наступне:
Ознайомтесь з концепціями авторизації Istio.
Встановіть Istio, використовуючи посібник з установки Istio.
Розгорніть два навантаження з іменами
curl
таtcp-echo
разом у просторі імен, наприклад,foo
. Обидва навантаження працюють з проксі Envoy попереду кожного з них. Навантаженняtcp-echo
слухає порти 9000, 9001 та 9002 та відповідає будь-якому отриманому трафіку з префіксомhello
. Наприклад, якщо ви надішлете “world” наtcp-echo
, він відповістьhello world
. Обʼєкт сервісу Kubernetestcp-echo
оголошує тільки порти 9000 і 9001, і не вказує порт 9002. Трафік на порт 9002 буде оброблятися через фільтр прохідного зʼєднання. Розгорніть приклад простору імен та навантаження, використовуючи наступну команду:$ kubectl create ns foo $ kubectl apply -f <(istioctl kube-inject -f @samples/tcp-echo/tcp-echo.yaml@) -n foo $ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@) -n foo
Перевірте, чи
curl
успішно комунікує зtcp-echo
на портах 9000 та 9001, використовуючи наступну команду:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9000 connection succeeded
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9001 connection succeeded
Перевірте, чи
curl
успішно комунікує зtcp-echo
на порту 9002. Вам потрібно надіслати трафік безпосередньо на IP-адресу podtcp-echo
, оскільки порт 9002 не визначений у обʼєкті сервісу Kubernetestcp-echo
. Отримайте IP-адресу pod і надішліть запит наступною командою:$ TCP_ECHO_IP=$(kubectl get pod "$(kubectl get pod -l app=tcp-echo -n foo -o jsonpath={.items..metadata.name})" -n foo -o jsonpath="{.status.podIP}") $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ "echo \"port 9002\" | nc $TCP_ECHO_IP 9002" | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9002 connection succeeded
Налаштування політики авторизації ALLOW для TCP-навантаження
Створіть політику авторизації
tcp-policy
для навантаженняtcp-echo
у просторі іменfoo
. Виконайте наступну команду для застосування політики, щоб дозволити запити на порти 9000 та 9001:$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: ALLOW rules: - to: - operation: ports: ["9000", "9001"] EOF
Перевірте, чи запити на порт 9000 дозволені, використовуючи наступну команду:
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9000 connection succeeded
Перевірте, чи запити на порт 9001 дозволені, використовуючи наступну команду:
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9001 connection succeeded
Перевірте, чи запити на порт 9002 відхилені. Це забезпечується політикою авторизації, яка також застосовується до фільтра прохідного зʼєднання, навіть якщо порт не оголошений явно в обʼєкті сервісу Kubernetes
tcp-echo
. Виконайте наступну команду та перевірте результат:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ "echo \"port 9002\" | nc $TCP_ECHO_IP 9002" | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Оновіть політику, щоб додати поле тільки для HTTP з назвою
methods
для порту 9000, використовуючи наступну команду:$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: ALLOW rules: - to: - operation: methods: ["GET"] ports: ["9000"] EOF
Перевірте, чи запити на порт 9000 відхилені. Це відбувається, тому що правило стає недійсним, коли використовуються поля тільки для HTTP (
methods
) для TCP-трафіку. Istio ігнорує недійсне правило ALLOW. Остаточний результат — запит відхилено, оскільки він не відповідає жодним ALLOW правилам. Виконайте наступну команду та перевірте результат:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Перевірте, чи запити на порт 9001 відхилені. Це відбувається, оскільки запити не відповідають жодним ALLOW правилам. Виконайте наступну команду та перевірте результат:
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Налаштування політики авторизації DENY для TCP-навантаження
Додайте політику DENY з полями тільки для HTTP, використовуючи наступну команду:
$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: DENY rules: - to: - operation: methods: ["GET"] EOF
Перевірте, чи запити на порт 9000 відхилені. Це відбувається тому, що Istio не розуміє поля тільки для HTTP при створенні правила DENY для TCP-порту, і через свою обмежувальну природу він блокує весь трафік до TCP-портів:
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Перевірте, чи запити на порт 9001 відхилені. Та сама причина, що й вище.
$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Додайте політику DENY з полями для TCP та HTTP, використовуючи наступну команду:
$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: DENY rules: - to: - operation: methods: ["GET"] ports: ["9000"] EOF
Перевірте, чи запити на порт 9000 відхилені. Це відбувається, тому що запит відповідає
ports
у згаданій вище політиці DENY.$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
Перевірте, чи запити на порт 9001 дозволені. Це відбувається, тому що запити не відповідають
ports
у політиці DENY:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9001 connection succeeded
Очищення
Видаліть простір імен foo
:
$ kubectl delete namespace foo