Manage Policy resources with kubectl
Use standard kubectl commands to work with Policy resources, just as you would with built-in Kubernetes resources.
For example, the following command creates a Policy resource defined in access-control-policy-allow.yaml with the name webapp-policy:
kubectl apply -f access-control-policy-allow.yaml
policy.k8s.nginx.org/webapp-policy configuredGet the resource by running:
kubectl get policy webapp-policy
NAME AGE
webapp-policy 27mFor kubectl get and similar commands, you can also use the short name pol instead of policy.
You can attach policies to VirtualServer, VirtualServerRoute, and Ingress resources. For example:
-
VirtualServer:
yaml apiVersion: k8s.nginx.org/v1 kind: VirtualServer metadata: name: cafe namespace: cafe spec: host: cafe.example.com tls: secret: cafe-secret policies: # spec policies - name: policy1 upstreams: - name: coffee service: coffee-svc port: 80 routes: - path: /tea policies: # route policies - name: policy2 namespace: cafe route: tea/tea - path: /coffee policies: # route policies - name: policy3 namespace: cafe action: pass: coffee ``` For VirtualServer, you can apply a policy: * to all routes (spec policies) * to a specific route (route policies) Route policies of the same type override spec policies. In the example above, if `policy-1` and `policy-3` are both `accessControl` policies, NGINX applies `policy-3` to requests for `cafe.example.com/coffee`. NGINX enforces this override: the spec policies apply in the `server` context of the configuration, and the route policies apply in the `location` context. As a result, the route policies of the same type take precedence. -
VirtualServerRoute, referenced by the VirtualServer above:
yaml apiVersion: k8s.nginx.org/v1 kind: VirtualServerRoute metadata: name: tea namespace: tea spec: host: cafe.example.com upstreams: - name: tea service: tea-svc port: 80 subroutes: # subroute policies - path: /tea policies: - name: policy4 namespace: tea action: pass: teaFor VirtualServerRoute, you can apply a policy to a subroute (subroute policies).
Subroute policies of the same type override spec policies. In the example above, if
policy-1(in the VirtualServer) andpolicy-4are bothaccessControlpolicies, NGINX appliespolicy-4to requests forcafe.example.com/tea. As with the VirtualServer, NGINX enforces this override.Subroute policies always override route policies, regardless of type. For example, NGINX Ingress Controller LTS ignores
policy-2from the VirtualServer route for the/teasubroute, because the subroute has its own policies,policy4in this case. If the subroute had no policies, NGINX Ingress Controller LTS would applypolicy-2instead. NGINX Ingress Controller LTS enforces this override: thelocationcontext for the subroute has either route policies or subroute policies, but never both. -
Ingress:
yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cafe-ingress annotations: nginx.org/policies: "webapp-policy" spec: ingressClassName: nginx tls: - hosts: - cafe.example.com secretName: tls-secret rules: - host: cafe.example.com http: paths: - path: /tea pathType: Prefix backend: service: name: tea-svc port: number: 80 - path: /coffee pathType: Prefix backend: service: name: coffee-svc port: number: 80For Ingress, you can apply policies:
- to a single Ingress
- to a master Ingress, where minion Ingresses inherit the policies
- to minion Ingresses, where minion policies override master policies
NGINX treats a policy as invalid if any of the following conditions is true:
- The policy doesn’t pass comprehensive validation.
- The policy isn’t present in the cluster.
- The policy doesn’t meet its type-specific requirements. For example, an
ingressMTLSpolicy requires TLS termination turned on in the VirtualServer.
For an invalid policy, NGINX returns the 500 status code for client requests, following these rules:
- If a policy is referenced in a VirtualServer
routeor a VirtualServerRoutesubroute, NGINX returns the 500 status code for requests to the URIs of that route or subroute. - If a policy is referenced in the VirtualServer
spec, NGINX returns the 500 status code for requests to all URIs of that VirtualServer.
If a policy is invalid, the VirtualServer or VirtualServerRoute gets the status state Warning, with a message that explains why the policy is invalid.
Two types of validation are available for the Policy resource:
- Structural validation, done by
kubectland the Kubernetes API server. - Comprehensive validation, done by NGINX Ingress Controller LTS.
The custom resource definition for the Policy includes a structural OpenAPI schema, which describes the type of every field of the resource.
If you try to create or update a resource that violates the structural schema, for example, if the resource uses a string value instead of an array of strings in the allow field, kubectl and the Kubernetes API server reject the resource.
-
Example of
kubectlvalidation:shell kubectl apply -f access-control-policy-allow.yaml error: error validating "access-control-policy-allow.yaml": error validating data: ValidationError(Policy.spec.accessControl.allow): invalid type for org.nginx.k8s.v1.Policy.spec.accessControl.allow: got "string", expected "array"; if you choose to ignore these errors, turn validation off with --validate=false -
Example of Kubernetes API server validation:
shell kubectl apply -f access-control-policy-allow.yaml --validate=false The Policy "webapp-policy" is invalid: spec.accessControl.allow: Invalid value: "string": spec.accessControl.allow in body must be of type array: "string"
If a resource passes structural validation, NGINX Ingress Controller LTS’s comprehensive validation runs next.
NGINX Ingress Controller LTS validates the fields of a Policy resource. If a resource is invalid, NGINX Ingress Controller LTS rejects it. The resource continues to exist in the cluster, but NGINX Ingress Controller LTS ignores it.
Use kubectl to check whether NGINX Ingress Controller LTS successfully applied a Policy configuration. For the example webapp-policy Policy, run:
kubectl describe pol webapp-policy
. . .
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal AddedOrUpdated 11s nginx-ingress-controller Policy default/webapp-policy was added or updatedThe events section includes a Normal event with the AddedOrUpdated reason, which tells you the configuration applied successfully.
If you create an invalid resource, NGINX Ingress Controller LTS rejects it and emits a Rejected event. For example, if you create a Policy webapp-policy with an invalid IP 10.0.0. in the allow field, you get:
kubectl describe policy webapp-policy
. . .
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Rejected 7s nginx-ingress-controller Policy default/webapp-policy is invalid and was rejected: spec.accessControl.allow[0]: Invalid value: "10.0.0.": must be a CIDR or IPThe events section includes a Warning event with the Rejected reason.
This information is also available in the status field of the Policy resource. Note the Status section of the Policy:
kubectl describe pol webapp-policy
. . .
Status:
Message: Policy default/webapp-policy is invalid and was rejected: spec.accessControl.allow[0]: Invalid value: "10.0.0.": must be a CIDR or IP
Reason: Rejected
State: InvalidWarningIf you make an existing resource invalid, NGINX Ingress Controller LTS rejects it.