Я хочу разработать сетевые политики в кластере Kubernetes, чтобы иметь детализированный общий контроль доступа между модулями.
Я подготовил настройку Kubernetes с 2 манифестами:
- Модуль nginx с 2 контейнерами, с 2 прослушивающими портами и возвращенными некоторыми общими данными, один - порт 80, другой - 81
- У меня есть 3 консольных модуля с 2 ярлыками включения / выключения: "allow80 "и" allow80 ".Таким образом, если присутствует «allow80», консольный модуль может получить доступ к dual-nginx через точку входа службы, порт 80. То же самое применяется для порта 81
У меня есть 3 консольных модуля:
- console-full - порты доступа 80 и 81, [allow80, allow81]
- console-part - порт 80 - включен, 81 - выкл, [allow80]
- console-no-доступ - как 80, так и 81 - ограничен []
Тестовая настройка.Он создаст все необходимые компоненты в пространстве имен «net-policy-test».
Для создания:
kubectl apply -f net_policy_test.yaml
Для очистки:
kubectl delete -f net_policy_test.yaml
apiVersion: v1
kind: Namespace
metadata:
name: net-policy-test
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx1
namespace: net-policy-test
data:
index.html: |
<!DOCTYPE html>
<html>
<head>
<title>nginx, instance1</title>
</head>
<body>
<h1>nginx, instance 1, port 80</h1>
</body>
</html>
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx2
namespace: net-policy-test
data:
index.html: |
<!DOCTYPE html>
<html>
<head>
<title>nginx, instance2</title>
</head>
<body>
<h1>nginx, instance 2, port 81</h1>
</body>
</html>
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf1
namespace: net-policy-test
data:
default.conf: |
server {
listen 80;
server_name localhost;
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;
}
}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf2
namespace: net-policy-test
data:
default.conf: |
server {
listen 81;
server_name localhost;
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;
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dual-nginx
namespace: net-policy-test
labels:
app: dual-nginx
environment: test
spec:
replicas: 1
selector:
matchLabels:
app: dual-nginx
template:
metadata:
labels:
app: dual-nginx
name: dual-nginx
spec:
containers:
- image: nginx
name: nginx1
ports:
- name: http1
containerPort: 80
volumeMounts:
- name: html1
mountPath: /usr/share/nginx/html
- name: config1
mountPath: /etc/nginx/conf.d
- image: nginx
name: nginx2
ports:
- name: http2
containerPort: 81
volumeMounts:
- name: html2
mountPath: /usr/share/nginx/html
- name: config2
mountPath: /etc/nginx/conf.d
volumes:
- name: html1
configMap:
name: nginx1
- name: html2
configMap:
name: nginx2
- name: config1
configMap:
name: nginx-conf1
- name: config2
configMap:
name: nginx-conf2
---
apiVersion: v1
kind: Service
metadata:
name: dual-nginx
namespace: net-policy-test
spec:
selector:
app: dual-nginx
ports:
- name: web1
port: 80
targetPort: http1
- name: web2
port: 81
targetPort: http2
---
# this console deployment will have full access to nginx
apiVersion: apps/v1
kind: Deployment
metadata:
name: console-full
namespace: net-policy-test
labels:
app: console-full
environment: test
nginx-access: full
spec:
replicas: 1
selector:
matchLabels:
app: console-full
template:
metadata:
labels:
app: console-full
name: console-full
allow80: "true"
allow81: "true"
spec:
containers:
- image: alpine:3.9
name: main
command: ["sh", "-c", "apk update && apk add curl && sleep 10000"]
---
# this console deployment will have partial access to nginx
apiVersion: apps/v1
kind: Deployment
metadata:
name: console-partial
namespace: net-policy-test
labels:
app: console-partial
environment: test
nginx-access: partial
spec:
replicas: 1
selector:
matchLabels:
app: console-partial
template:
metadata:
labels:
app: console-partial
name: console-partial
allow80: "true"
spec:
containers:
- image: alpine:3.9
name: main
command: ["sh", "-c", "apk update && apk add curl && sleep 10000"]
---
# this console deployment will have no access to nginx
apiVersion: apps/v1
kind: Deployment
metadata:
name: console-no-access
namespace: net-policy-test
labels:
app: console-no-access
environment: test
nginx-access: none
spec:
replicas: 1
selector:
matchLabels:
app: console-no-access
template:
metadata:
labels:
app: console-no-access
name: console-no-access
spec:
containers:
- image: alpine:3.9
name: main
command: ["sh", "-c", "apk update && apk add curl && sleep 10000"]
И политики, опять же, применяются:
kubectl apply -f policies.yaml
Для очистки:
kubectl delete -f policies.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: nginx-restrict80
spec:
podSelector:
matchLabels:
app: "dual-nginx"
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
allow80: "true"
ports:
- protocol: TCP
port: 80
- from:
- podSelector:
matchLabels:
allow81: "true"
ports:
- protocol: TCP
port: 81
Если я оставлю только одно условие с «from» для одного порта, оно будет работать как положено.У меня есть или нет доступ к порту, в зависимости от наличия соответствующей метки, allow80 или allow81
Если присутствуют 2 условия, частичный модуль имеет доступ к обоим портам 80 и 81:
- Переключиться в правое пространство имен:
kubectl config set-context --current --namespace=net-policy-test
Проверьте метки:
kubectl get pods -l allow80
NAME READY STATUS RESTARTS AGE
console-full-78d5499959-p5kbb 1/1 Running 1 4h14m
console-partial-6679745d79-kbs5w 1/1 Running 1 4h14m
kubectl get pods -l allow81
NAME READY STATUS RESTARTS AGE
console-full-78d5499959-p5kbb 1/1 Running 1 4h14m
Проверьте доступ из модуля «console-part -...», который должен иметь доступ к порту 80, а не 81:
kubectl exec -ti console-partial-6679745d79-kbs5w curl http://dual-nginx:80
<!DOCTYPE html>
<html>
<head>
<title>nginx, instance1</title>
</head>
<body>
<h1>nginx, instance 1, port 80</h1>
</body>
</html>
kubectl exec -ti console-partial-6679745d79-kbs5w curl http://dual-nginx:81
<!DOCTYPE html>
<html>
<head>
<title>nginx, instance2</title>
</head>
<body>
<h1>nginx, instance 2, port 81</h1>
</body>
</html>
Модуль с частичным доступом имеет доступ к портам 80 и 81.
Блок, не имеющий меток (console-no-access-), не имеющий доступа ни к одному из портов, что ожидается
Это похоже на то, что описано в этой презентации: YoutubeЗащита кластерной сети с помощью сетевых политик - Ахмет Балкан, Google .Таким образом, по крайней мере один флаг «allow80» или «allow81» дает доступ ко всему.Почему?
Теперь вопросы:
- Ожидаемое поведение?
- Как создать простой контроль доступа на основе флагов, чтобы автоматизировать его или передать администраторам?Кто может легко произвести их в большом количестве?