Добавление пространства имен kube-system в белый список с помощью NetworkPolicy

У меня есть мультитенантный кластер, в котором мультитенантность достигается через пространства имен. У каждого арендатора есть собственное пространство имен. Модули одного арендатора не могут взаимодействовать с модулями другого арендатора. Однако некоторые модули в каждом арендаторе должны предоставлять услугу в Интернете с помощью Ingress.

Это я, как далеко я продвинулся (я использую Calico):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: tenant1-isolate-namespace
  namespace: tenant1
spec:
  policyTypes:
  - Ingress
  podSelector: {} # Select all pods in this namespace
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: tenant1 # white list current namespace

Развернутый для каждого пространства имен (tenant1, tenant2, ...), это ограничивает обмен данными между модулями в их пространстве имен. Однако это не позволяет модулям из пространства имен kube-system взаимодействовать с модулями в этом пространстве имен.

Однако пространство имен kube-system по умолчанию не имеет меток, поэтому я не могу специально занести это пространство имен в белый список.

Я нашел (грязный) обходной путь для этой проблемы, вручную присвоив ему метку:

kubectl label namespace/kube-system permission=talk-to-all

И добавляем правило белого списка в сетевую политику:

...
  - from:
    - namespaceSelector:
        matchLabels:
          permission: talk-to-all # allow namespaces that have the "talk-to-all privilege"

Есть ли лучшее решение без указания kube-system метки вручную?

Изменить: я попытался дополнительно добавить правило «ИЛИ», чтобы разрешить связь от модулей с меткой «app = nginx-ingress», но безуспешно:

  - from
    ...
    - podSelector:
        matchLabels:
          app: nginx-ingress # Allow pods that have the app=nginx-ingress label

person mitchkman    schedule 12.06.2018    source источник
comment
Удалось ли вам предоставить доступ к Интернету по отдельному модулю в каждом ns, но по-прежнему препятствовать межкластерному взаимодействию между пространствами имен? Я попробовал ваш грязный обходной путь, но мои выделенные модули недоступны из Интернета (AWS ELB) ... В моей сетевой политике для входа у меня есть - podSelector: {} - namespaceSelector: matchLabels: permission: kube-system Тот факт, что я могу получить доступ к своим защищенное пространство имен из модулей в пространстве имен kube-system не позволяет мне получить доступ к экспонированному модулю ELB в защищенном пространстве имен - похоже, что внешний трафик из ELB не проходит через пространство имен kube-system   -  person user62058    schedule 07.11.2018


Ответы (4)


apiVersion: network.k8s.io/v1 < / сильный>

NamespaceSelector предназначен для сопоставления пространств имен только по меткам. Невозможно выбрать пространство имен по имени.

PodSelector может выбирать модули только в том же пространстве имен, что и объект NetworkPolicy. Для объектов, расположенных в разных пространствах имен, возможен только выбор всего пространства имен.

Вот пример реализации сетевой политики Kubernetes:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

Перейдите по этой ссылке, чтобы прочитать хорошее объяснение всей концепции сетевой политики, или эту ссылку, чтобы посмотреть лекцию.

apiVersion: projectcalico.org/v3

Calico API дает вам больше возможностей для написания правил NetworkPolicy, поэтому в какой-то момент вы сможете достичь своей цели с меньшими усилиями и умопомрачительными усилиями.

Например, используя реализацию сетевой политики Calico, вы можете:

  • установить действие для правила (Разрешить, Запретить, Журнал, Пропустить),
  • использовать отрицательное соответствие (протокол, notProtocol, селектор, notSelector),
  • применять более сложные селекторы меток (имеет (k), k отсутствует в {‘v1’, ‘v2’}),
  • комбинировать селекторы с оператором &&,
  • использовать диапазон портов (порты: [8080, «1234: 5678», «named-port»]),
  • сопоставить модули в других пространствах имен.

Но все же вы можете сопоставлять пространства имен только по меткам.

Прочтите документацию по Calico для получения подробной информации.

Вот пример реализации сетевой политики Calico:

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-tcp-6379
  namespace: production
spec:
  selector: role == 'database'
  types:
  - Ingress
  - Egress
  ingress:
  - action: Allow
    protocol: TCP
    source:
      selector: role == 'frontend'
    destination:
      ports:
      - 6379
  egress:
  - action: Allow
person VASャ    schedule 12.06.2018
comment
В calico теперь вы также можете сопоставлять пространства имен по имени: выберите конкретное пространство имен по имени, используя метку projectcalico.org/name. См. документацию по namespaceSelector. - person Julian Dm; 10.12.2020
comment
Итак, это метка, которая равна имени пространства имен, но селектор по-прежнему может использовать только метки. Верно? - person VASャ; 10.12.2020
comment
селектор выбирает ресурсы по их метке (т. е. модули, службы). namespaceSelector выбирает ресурсы по метке их пространства имен. Их также можно использовать вместе. И да, afaik projectcalico.org/name - это специальный идентификатор, указывающий на имя пространства имен. - person Julian Dm; 10.12.2020

Действительно, tenant1 модулям потребуется доступ к kube-dns в пространстве имен kube-system.

Одним из подходов, не требующих пометки пространства имен kube-system, является следующая политика. Хотя kube-dns может находиться в любом пространстве имен при таком подходе, поэтому он может не подходить для вас.

---                                                                                                                                                                                                           
# Default deny all ingress & egress policy, except allow kube-dns                                                                                                                                             
# All traffic except this must be explicity allowed.                                                                                                                                                          
kind: NetworkPolicy                                                                                                                                                                                           
apiVersion: networking.k8s.io/v1                                                                                                                                                                              
metadata:                                                                                                                                                                                                     
  name: default-deny-all-except-kube-dns                                                                                                                                                                      
  namespace: tenant1                                                                                                                                                                                        
spec:                                                                                                                                                                                                         
  podSelector: {}                                                                                                                                                                                             
  egress:                                                                                                                                                                                                     
  - to:                                                                                                                                                                                                       
    - podSelector:                                                                                                                                                                                            
        matchLabels:                                                                                                                                                                                          
          k8s-app: kube-dns                                                                                                                                                                                   
 - ports:             
   - protocol: TCP                                                                                                                                                                                         
     port: 53                                                                                                                                                                                                                                                                                     
   - protocol: UDP                                                                                                                                                                                           
     port: 53                                                                                                                                                                                                
 policyTypes:                                                                                                                                                                                                
 - Ingress                                                                                                                                                                                                   
 - Egress   

Затем вам также понадобится «разрешить все в политике пространства имен», как показано ниже:

---                                                                                                                                                                                                           
# Allow intra namespace traffic for development purposes only.                                                                                                                                                
kind: NetworkPolicy                                                                                                                                                                                           
apiVersion: networking.k8s.io/v1                                                                                                                                                                              
metadata:                                                                                                                                                                                                     
  name: allow-intra-namespace                                                                                                                                                                                 
  namespace: tenant1                                                                                                                                                                                        
spec:                                                                                                                                                                                                         
  podSelector:                                                                                                                                                                                                
    matchLabels:                                                                                                                                                                                              
  ingress:                                                                                                                                                                                                    
  - from:                                                                                                                                                                                                     
    - podSelector: {}                                                                                                                                                                                         
  egress:                                                                                                                                                                                                     
  - to:                                                                                                                                                                                                       
    - podSelector: {}                                                                                                                                                                                         
  policyTypes:                                                                                                                                                                                                
  - Ingress                                                                                                                                                                                                   
  - Egress

Наконец, вы захотите добавить определенные политики, такие как правило входа. Было бы лучше заменить политику allow-intra-namespace конкретными правилами, подходящими для отдельных модулей, что может делать ваш tenant1.

Они были адаптированы с этого веб-сайта: https://github.com/ahmetb/kubernetes-network-policy-recipes

person Karl    schedule 28.06.2018
comment
Я уже некоторое время борюсь с этим - ваше правило kube-dns сработало. Очень признателен! - person Pat; 05.03.2020

Если я правильно понял, вы используете бязь. Просто используйте их пример о том, как реализовать default-deny, не нарушая связи kube-dns. Найдено здесь

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: deny-app-policy
spec:
  namespaceSelector: has(projectcalico.org/name) && projectcalico.org/name not in {"kube-system", "calico-system"}
  types:
  - Ingress
  - Egress
  egress:
  # allow all namespaces to communicate to DNS pods
  - action: Allow
    protocol: UDP
    destination:
      selector: 'k8s-app == "kube-dns"'
      ports:
      - 53
person Julian Dm    schedule 10.12.2020

Я на k3os с фланелевым CNI по умолчанию. Он имеет метку по умолчанию в пространстве имен kube-system:

$ kubectl describe ns kube-system
Name:         kube-system
Labels:       kubernetes.io/metadata.name=kube-system
Annotations:  <none>
Status:       Active

Это работает для меня:

- namespaceSelector:
    matchLabels:
      kubernetes.io/metadata.name: kube-system

Вот мой полный yaml, который разрешает весь внешний трафик и kube-dns в пространстве имен kube-system для выхода:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-egress
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
      - port: 53
        protocol: UDP
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 10.0.0.0/8
        - 172.16.0.0/12
        - 192.168.0.0/16
person Shawn    schedule 22.07.2021