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)
|
||||
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/kuryrnetpolicy.yaml
|
||||
if [ "$KURYR_K8S_CONTAINERIZED_DEPLOYMENT" == "True" ]; then
|
||||
if is_service_enabled kuryr-daemon; then
|
||||
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
|
||||
trunk_ports
|
||||
network_namespace
|
||||
network_policy
|
||||
testing_connectivity
|
||||
testing_nested_connectivity
|
||||
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_NAMESPACES = K8S_API_BASE + '/namespaces'
|
||||
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_NPWG_CRD = '/apis/k8s.cni.cncf.io/v1'
|
||||
@ -27,6 +28,7 @@ K8S_OBJ_ENDPOINTS = 'Endpoints'
|
||||
K8S_OBJ_POLICY = 'NetworkPolicy'
|
||||
|
||||
K8S_OBJ_KURYRNET = 'KuryrNet'
|
||||
K8S_OBJ_KURYRNETPOLICY = 'KuryrNetPolicy'
|
||||
|
||||
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_STATE = K8S_ANNOTATION_PREFIX + '-lbaas-state'
|
||||
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_NOTIF = K8S_ANNOTATION_PREFIX + '-lbaas-route-notif'
|
||||
K8S_ANNOTATION_ROUTE_STATE = K8S_ANNOTATION_PREFIX + '-route-state'
|
||||
|
@ -15,7 +15,12 @@
|
||||
|
||||
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 import exceptions
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -24,7 +29,103 @@ class NetworkPolicyDriver(base.NetworkPolicyDriver):
|
||||
"""Provides security groups actions based on K8s Network Policies"""
|
||||
|
||||
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):
|
||||
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,
|
||||
verify=self.verify_server,
|
||||
headers=header)
|
||||
if response.status_code == requests.codes.not_found:
|
||||
raise exc.K8sResourceNotFound(response.text)
|
||||
if not response.ok:
|
||||
raise exc.K8sClientException(response.text)
|
||||
result = response.json() if json else response.text
|
||||
|
Loading…
Reference in New Issue
Block a user