Implement NP SG create/delete actions
This commit implements NP driver actions for creating/updating SG and SG rules. It also creates KuryrNetPolicy as a CRD so we don't have to rely on the slow neutron API for time-costly operations such as listing SG and so. Security group rules and label matching will be handled in a follow-up patch, as well as storing CRD object_id in a network policy annotation. Unit tests will also be added after some more functionality is added with the remaining patch series. Partially-Implements: bp/k8s-network-policies Change-Id: I6d45a462e812b24073b529144fc0843e8725a06e
This commit is contained in:
parent
95953a6f67
commit
4465c2062a
@ -902,6 +902,7 @@ if [[ "$1" == "stack" && "$2" == "extra" ]]; then
|
|||||||
KURYR_K8S_CONTAINERIZED_DEPLOYMENT=$(trueorfalse False KURYR_K8S_CONTAINERIZED_DEPLOYMENT)
|
KURYR_K8S_CONTAINERIZED_DEPLOYMENT=$(trueorfalse False KURYR_K8S_CONTAINERIZED_DEPLOYMENT)
|
||||||
if is_service_enabled kuryr-kubernetes; then
|
if is_service_enabled kuryr-kubernetes; then
|
||||||
/usr/local/bin/kubectl apply -f ${KURYR_HOME}/kubernetes_crds/kuryrnet.yaml
|
/usr/local/bin/kubectl apply -f ${KURYR_HOME}/kubernetes_crds/kuryrnet.yaml
|
||||||
|
/usr/local/bin/kubectl apply -f ${KURYR_HOME}/kubernetes_crds/kuryrnetpolicy.yaml
|
||||||
if [ "$KURYR_K8S_CONTAINERIZED_DEPLOYMENT" == "True" ]; then
|
if [ "$KURYR_K8S_CONTAINERIZED_DEPLOYMENT" == "True" ]; then
|
||||||
if is_service_enabled kuryr-daemon; then
|
if is_service_enabled kuryr-daemon; then
|
||||||
build_kuryr_containers $CNI_BIN_DIR $CNI_CONF_DIR True
|
build_kuryr_containers $CNI_BIN_DIR $CNI_CONF_DIR True
|
||||||
|
@ -37,6 +37,7 @@ This section describes how you can install and configure kuryr-kubernetes
|
|||||||
default_configuration
|
default_configuration
|
||||||
trunk_ports
|
trunk_ports
|
||||||
network_namespace
|
network_namespace
|
||||||
|
network_policy
|
||||||
testing_connectivity
|
testing_connectivity
|
||||||
testing_nested_connectivity
|
testing_nested_connectivity
|
||||||
containerized
|
containerized
|
||||||
|
98
doc/source/installation/network_policy.rst
Normal file
98
doc/source/installation/network_policy.rst
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
Enable network policy support functionality
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
Please follow the next steps in order to enable the network policy support
|
||||||
|
feature:
|
||||||
|
|
||||||
|
1. Enable the policy handler to response to network policy events. As this is
|
||||||
|
not enabled by default you'd have to explicitly add that to the list of
|
||||||
|
enabled handlers at kuryr.conf (further info on how to do this can be found
|
||||||
|
at :doc:`./devstack/containerized`)::
|
||||||
|
|
||||||
|
[kubernetes]
|
||||||
|
enabled_handlers=vif,lb,lbaasspec,policy
|
||||||
|
|
||||||
|
Note that you need to restart the kuryr controller after applying the above
|
||||||
|
detailed steps. For devstack non-containerized deployments::
|
||||||
|
|
||||||
|
$ sudo systemctl restart devstack@kuryr-kubernetes.service
|
||||||
|
|
||||||
|
|
||||||
|
Same for containerized deployments::
|
||||||
|
|
||||||
|
$ kubectl -n kube-system get pod | grep kuryr-controller
|
||||||
|
$ kubectl -n kube-system delete pod KURYR_CONTROLLER_POD_NAME
|
||||||
|
|
||||||
|
|
||||||
|
For directly enabling the driver when deploying with devstack, you just need
|
||||||
|
to add the policy handler with::
|
||||||
|
|
||||||
|
KURYR_ENABLED_HANDLERS=vif,lb,lbaasspec,policy
|
||||||
|
|
||||||
|
|
||||||
|
Testing the network policy support functionality
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
1. Given a yaml file with a network policy, such as::
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
2. Apply the network policy::
|
||||||
|
|
||||||
|
$ kubectl apply -f network_policy.yml
|
||||||
|
|
||||||
|
3. Check that the resources has been created::
|
||||||
|
|
||||||
|
$ kubectl get kuryrnetpolicies
|
||||||
|
NAME AGE
|
||||||
|
np-test-network-policy 2s
|
||||||
|
|
||||||
|
$ kubectl get networkpolicies
|
||||||
|
NAME POD-SELECTOR AGE
|
||||||
|
test-network-policy role=db 2s
|
||||||
|
|
||||||
|
$ openstack security group list | grep test-network-policy
|
||||||
|
| dabdf308-7eed-43ef-a058-af84d1954acb | test-network-policy
|
||||||
|
|
||||||
|
4. Check that the teardown of the resources once the network policy is removed::
|
||||||
|
|
||||||
|
$ kubectl delete -f network_policy.yml
|
||||||
|
|
||||||
|
$ kubectl get kuryrnetpolicies
|
||||||
|
|
||||||
|
$ kubectl get networkpolicies
|
||||||
|
|
||||||
|
$ openstack security group list | grep test-network-policy
|
14
kubernetes_crds/kuryrnetpolicy.yaml
Normal file
14
kubernetes_crds/kuryrnetpolicy.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: apiextensions.k8s.io/v1beta1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
name: kuryrnetpolicies.openstack.org
|
||||||
|
spec:
|
||||||
|
group: openstack.org
|
||||||
|
version: v1
|
||||||
|
scope: Namespaced
|
||||||
|
names:
|
||||||
|
plural: kuryrnetpolicies
|
||||||
|
singular: kuryrnetpolicy
|
||||||
|
kind: KuryrNetPolicy
|
||||||
|
shortNames:
|
||||||
|
- knp
|
@ -16,6 +16,7 @@
|
|||||||
K8S_API_BASE = '/api/v1'
|
K8S_API_BASE = '/api/v1'
|
||||||
K8S_API_NAMESPACES = K8S_API_BASE + '/namespaces'
|
K8S_API_NAMESPACES = K8S_API_BASE + '/namespaces'
|
||||||
K8S_API_CRD = '/apis/openstack.org/v1'
|
K8S_API_CRD = '/apis/openstack.org/v1'
|
||||||
|
K8S_API_CRD_NAMESPACES = K8S_API_CRD + '/namespaces'
|
||||||
K8S_API_POLICIES = '/apis/networking.k8s.io/v1/networkpolicies'
|
K8S_API_POLICIES = '/apis/networking.k8s.io/v1/networkpolicies'
|
||||||
|
|
||||||
K8S_API_NPWG_CRD = '/apis/k8s.cni.cncf.io/v1'
|
K8S_API_NPWG_CRD = '/apis/k8s.cni.cncf.io/v1'
|
||||||
@ -27,6 +28,7 @@ K8S_OBJ_ENDPOINTS = 'Endpoints'
|
|||||||
K8S_OBJ_POLICY = 'NetworkPolicy'
|
K8S_OBJ_POLICY = 'NetworkPolicy'
|
||||||
|
|
||||||
K8S_OBJ_KURYRNET = 'KuryrNet'
|
K8S_OBJ_KURYRNET = 'KuryrNet'
|
||||||
|
K8S_OBJ_KURYRNETPOLICY = 'KuryrNetPolicy'
|
||||||
|
|
||||||
K8S_POD_STATUS_PENDING = 'Pending'
|
K8S_POD_STATUS_PENDING = 'Pending'
|
||||||
|
|
||||||
@ -35,6 +37,7 @@ K8S_ANNOTATION_VIF = K8S_ANNOTATION_PREFIX + '-vif'
|
|||||||
K8S_ANNOTATION_LBAAS_SPEC = K8S_ANNOTATION_PREFIX + '-lbaas-spec'
|
K8S_ANNOTATION_LBAAS_SPEC = K8S_ANNOTATION_PREFIX + '-lbaas-spec'
|
||||||
K8S_ANNOTATION_LBAAS_STATE = K8S_ANNOTATION_PREFIX + '-lbaas-state'
|
K8S_ANNOTATION_LBAAS_STATE = K8S_ANNOTATION_PREFIX + '-lbaas-state'
|
||||||
K8S_ANNOTATION_NET_CRD = K8S_ANNOTATION_PREFIX + '-net-crd'
|
K8S_ANNOTATION_NET_CRD = K8S_ANNOTATION_PREFIX + '-net-crd'
|
||||||
|
K8S_ANNOTATION_NETPOLICY_CRD = K8S_ANNOTATION_PREFIX + '-netpolicy-crd'
|
||||||
K8S_ANNOTATION_LBAAS_RT_STATE = K8S_ANNOTATION_PREFIX + '-lbaas-route-state'
|
K8S_ANNOTATION_LBAAS_RT_STATE = K8S_ANNOTATION_PREFIX + '-lbaas-route-state'
|
||||||
K8S_ANNOTATION_LBAAS_RT_NOTIF = K8S_ANNOTATION_PREFIX + '-lbaas-route-notif'
|
K8S_ANNOTATION_LBAAS_RT_NOTIF = K8S_ANNOTATION_PREFIX + '-lbaas-route-notif'
|
||||||
K8S_ANNOTATION_ROUTE_STATE = K8S_ANNOTATION_PREFIX + '-route-state'
|
K8S_ANNOTATION_ROUTE_STATE = K8S_ANNOTATION_PREFIX + '-route-state'
|
||||||
|
@ -15,7 +15,12 @@
|
|||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from neutronclient.common import exceptions as n_exc
|
||||||
|
|
||||||
|
from kuryr_kubernetes import clients
|
||||||
|
from kuryr_kubernetes import constants
|
||||||
from kuryr_kubernetes.controller.drivers import base
|
from kuryr_kubernetes.controller.drivers import base
|
||||||
|
from kuryr_kubernetes import exceptions
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -24,7 +29,103 @@ class NetworkPolicyDriver(base.NetworkPolicyDriver):
|
|||||||
"""Provides security groups actions based on K8s Network Policies"""
|
"""Provides security groups actions based on K8s Network Policies"""
|
||||||
|
|
||||||
def ensure_network_policy(self, policy, project_id):
|
def ensure_network_policy(self, policy, project_id):
|
||||||
pass
|
neutron = clients.get_neutron_client()
|
||||||
|
LOG.debug("Creating network policy %s" % policy['metadata']['name'])
|
||||||
|
if self._get_kuryrnetpolicy_crd(policy):
|
||||||
|
LOG.debug("Already existing CRD")
|
||||||
|
return
|
||||||
|
security_group_body = {
|
||||||
|
"security_group":
|
||||||
|
{
|
||||||
|
"name": policy['metadata']['name'],
|
||||||
|
"project_id": project_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
sg = neutron.create_security_group(body=security_group_body)
|
||||||
|
except n_exc.NeutronClientException:
|
||||||
|
LOG.exception("Error creating security group for network policy. ")
|
||||||
|
raise
|
||||||
|
try:
|
||||||
|
self._add_kuryrnetpolicy_crd(policy, project_id,
|
||||||
|
sg['security_group']['id'])
|
||||||
|
except exceptions.K8sClientException:
|
||||||
|
LOG.exception("Rolling back security groups")
|
||||||
|
neutron.delete_security_group(sg['security_group']['id'])
|
||||||
|
raise
|
||||||
|
|
||||||
def release_network_policy(self, policy, project_id):
|
def release_network_policy(self, policy, project_id):
|
||||||
pass
|
neutron = clients.get_neutron_client()
|
||||||
|
netpolicy_crd = self._get_kuryrnetpolicy_crd(policy)
|
||||||
|
if netpolicy_crd is not None:
|
||||||
|
try:
|
||||||
|
sg_id = netpolicy_crd['spec']['securityGroupId']
|
||||||
|
neutron.delete_security_group(sg_id)
|
||||||
|
except n_exc.NotFound:
|
||||||
|
LOG.debug("Security Group not found: %s", sg_id)
|
||||||
|
except n_exc.NeutronClientException:
|
||||||
|
LOG.exception("Error deleting security group %s.", sg_id)
|
||||||
|
raise
|
||||||
|
self._del_kuryrnetpolicy_crd(
|
||||||
|
netpolicy_crd['metadata']['name'],
|
||||||
|
netpolicy_crd['metadata']['namespace'])
|
||||||
|
|
||||||
|
def _get_kuryrnetpolicy_crd(self, policy):
|
||||||
|
kubernetes = clients.get_kubernetes_client()
|
||||||
|
netpolicy_crd_name = "np-" + policy['metadata']['name']
|
||||||
|
netpolicy_crd_namespace = policy['metadata']['namespace']
|
||||||
|
try:
|
||||||
|
netpolicy_crd = kubernetes.get('{}/{}/kuryrnetpolicies/{}'.format(
|
||||||
|
constants.K8S_API_CRD_NAMESPACES, netpolicy_crd_namespace,
|
||||||
|
netpolicy_crd_name))
|
||||||
|
except exceptions.K8sResourceNotFound:
|
||||||
|
return None
|
||||||
|
except exceptions.K8sClientException:
|
||||||
|
LOG.exception("Kubernetes Client Exception.")
|
||||||
|
raise
|
||||||
|
return netpolicy_crd
|
||||||
|
|
||||||
|
def _add_kuryrnetpolicy_crd(self, policy, project_id, sg_id):
|
||||||
|
kubernetes = clients.get_kubernetes_client()
|
||||||
|
netpolicy_crd_name = "np-" + policy['metadata']['name']
|
||||||
|
netpolicy_crd_namespace = policy['metadata']['namespace']
|
||||||
|
netpolicy_crd = {
|
||||||
|
'apiVersion': 'openstack.org/v1',
|
||||||
|
'kind': constants.K8S_OBJ_KURYRNETPOLICY,
|
||||||
|
'metadata': {
|
||||||
|
'name': netpolicy_crd_name,
|
||||||
|
'namespace': netpolicy_crd_namespace,
|
||||||
|
'annotations': {
|
||||||
|
'policy': policy
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'spec': {
|
||||||
|
'securityGroupName': policy['metadata']['name'],
|
||||||
|
'securityGroupId': sg_id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
LOG.debug("Creating KuryrNetPolicy CRD %s" % netpolicy_crd)
|
||||||
|
kubernetes_post = '{}/{}/kuryrnetpolicies'.format(
|
||||||
|
constants.K8S_API_CRD_NAMESPACES,
|
||||||
|
netpolicy_crd_namespace)
|
||||||
|
kubernetes.post(kubernetes_post, netpolicy_crd)
|
||||||
|
except exceptions.K8sClientException:
|
||||||
|
LOG.exception("Kubernetes Client Exception creating kuryrnetpolicy"
|
||||||
|
" CRD. %s" % exceptions.K8sClientException)
|
||||||
|
raise
|
||||||
|
return netpolicy_crd
|
||||||
|
|
||||||
|
def _del_kuryrnetpolicy_crd(self, netpolicy_crd_name,
|
||||||
|
netpolicy_crd_namespace):
|
||||||
|
kubernetes = clients.get_kubernetes_client()
|
||||||
|
try:
|
||||||
|
LOG.debug("Deleting KuryrNetPolicy CRD %s" % netpolicy_crd_name)
|
||||||
|
kubernetes.delete('{}/{}/kuryrnetpolicies/{}'.format(
|
||||||
|
constants.K8S_API_CRD_NAMESPACES,
|
||||||
|
netpolicy_crd_namespace,
|
||||||
|
netpolicy_crd_name))
|
||||||
|
except exceptions.K8sClientException:
|
||||||
|
LOG.exception("Kubernetes Client Exception deleting kuryrnetpolicy"
|
||||||
|
" CRD.")
|
||||||
|
raise
|
||||||
|
@ -76,6 +76,8 @@ class K8sClient(object):
|
|||||||
response = requests.get(url, cert=self.cert,
|
response = requests.get(url, cert=self.cert,
|
||||||
verify=self.verify_server,
|
verify=self.verify_server,
|
||||||
headers=header)
|
headers=header)
|
||||||
|
if response.status_code == requests.codes.not_found:
|
||||||
|
raise exc.K8sResourceNotFound(response.text)
|
||||||
if not response.ok:
|
if not response.ok:
|
||||||
raise exc.K8sClientException(response.text)
|
raise exc.K8sClientException(response.text)
|
||||||
result = response.json() if json else response.text
|
result = response.json() if json else response.text
|
||||||
|
Loading…
Reference in New Issue
Block a user