Getting Started¶
Before you Begin¶
You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by installing minikube or kind, or you can use one of these Kubernetes playgrounds:
You also need the Trivy-Operator to be installed in the trivy-system
namespace, e.g. with
kubectl or Helm. Let's also assume that the operator is
configured to discover built-in Kubernetes resources in all namespaces, except kube-system
and trivy-system
.
Workloads Scanning¶
Let's create the nginx
Deployment that we know is vulnerable:
kubectl create deployment nginx --image nginx:1.16
When the nginx
Deployment is created, the operator immediately detects its current revision (aka active ReplicaSet)
and scans the nginx:1.16
image for vulnerabilities. It also audits the ReplicaSet's specification for common pitfalls
such as running the nginx
container as root.
If everything goes fine, the operator saves scan reports as VulnerabilityReport and ConfigAuditReport resources in the
default
namespace. Reports are named after the scanned ReplicaSet. For image vulnerability scans, the operator creates
a VulnerabilityReport for each different container. In this example there is just one container image called nginx
:
kubectl get vulnerabilityreports -o wide
Result
NAME REPOSITORY TAG SCANNER AGE CRITICAL HIGH MEDIUM LOW UNKNOWN
replicaset-nginx-78449c65d4-nginx library/nginx 1.16 Trivy 85s 33 62 49 114 1
kubectl get configauditreports -o wide
Result
NAME SCANNER AGE CRITICAL HIGH MEDIUM LOW
replicaset-nginx-78449c65d4 Trivy-Operator 2m7s 0 0 6 7
Notice that scan reports generated by the operator are controlled by Kubernetes workloads. In our example,
VulnerabilityReport and ConfigAuditReport resources are controlled by the active ReplicaSet of the nginx
Deployment:
kubectl tree deploy nginx
Result
NAMESPACE NAME READY REASON AGE
default Deployment/nginx - 7h2m
default └─ReplicaSet/nginx-78449c65d4 - 7h2m
default ├─ConfigAuditReport/replicaset-nginx-78449c65d4 - 2m31s
default ├─Pod/nginx-78449c65d4-5wvdx True 7h2m
default └─VulnerabilityReport/replicaset-nginx-78449c65d4-nginx - 2m7s
Note
The tree command is a kubectl plugin to browse Kubernetes object hierarchies as a tree.
Moving forward, let's update the container image of the nginx
Deployment from nginx:1.16
to nginx:1.17
. This will
trigger a rolling update of the Deployment and eventually create another ReplicaSet.
kubectl set image deployment nginx nginx=nginx:1.17
Even this time the operator will pick up changes and rescan our Deployment with updated configuration:
kubectl tree deploy nginx
Result
NAMESPACE NAME READY REASON AGE
default Deployment/nginx - 7h5m
default ├─ReplicaSet/nginx-5fbc65fff - 2m36s
default │ ├─ConfigAuditReport/replicaset-nginx-5fbc65fff - 2m36s
default │ ├─Pod/nginx-5fbc65fff-j7zl2 True 2m36s
default │ └─VulnerabilityReport/replicaset-nginx-5fbc65fff-nginx - 2m22s
default └─ReplicaSet/nginx-78449c65d4 - 7h5m
default ├─ConfigAuditReport/replicaset-nginx-78449c65d4 - 5m46s
default └─VulnerabilityReport/replicaset-nginx-78449c65d4-nginx - 5m22s
By following this guide you could realize that the operator knows how to attach VulnerabilityReport and
ConfigAuditReport resources to build-in Kubernetes objects. What's more, in this approach where a custom resource
inherits a life cycle of the built-in resource we could leverage Kubernetes garbage collection. For example, when the
previous ReplicaSet named nginx-78449c65d4
is deleted the VulnerabilityReport named replicaset-nginx-78449c65d4-nginx
as well as the ConfigAuditReport named replicaset-nginx-78449c65d46
are automatically garbage collected.
Tip
If you only want the latest ReplicaSet in your Deployment to be scanned for vulnerabilities, you can set the value
of the OPERATOR_VULNERABILITY_SCANNER_SCAN_ONLY_CURRENT_REVISIONS
environment variable to true
in the operator's
deployment descriptor. This is useful to identify vulnerabilities that impact only the running workloads.
Tip
If you only want the latest ReplicaSet in your Deployment to be scanned for config audit, you can set the value
of the OPERATOR_CONFIG_AUDIT_SCANNER_SCAN_ONLY_CURRENT_REVISIONS
environment variable to true
in the operator's
deployment descriptor. This is useful to identify config issues that impact only the running workloads.
Tip
You can get and describe vulnerabilityreports
and configauditreports
as built-in Kubernetes objects:
kubectl get vulnerabilityreport replicaset-nginx-5fbc65fff-nginx -o json
kubectl describe configauditreport replicaset-nginx-5fbc65fff
Notice that scaling up the nginx
Deployment will not schedule new scans because all replica Pods refer to the same Pod
template defined by the nginx-5fbc65fff
ReplicaSet.
kubectl scale deploy nginx --replicas 3
kubectl tree deploy nginx
Result
NAMESPACE NAME READY REASON AGE
default Deployment/nginx - 7h6m
default ├─ReplicaSet/nginx-5fbc65fff - 4m7s
default │ ├─ConfigAuditReport/replicaset-nginx-5fbc65fff - 4m7s
default │ ├─Pod/nginx-5fbc65fff-458n7 True 8s
default │ ├─Pod/nginx-5fbc65fff-fk847 True 8s
default │ ├─Pod/nginx-5fbc65fff-j7zl2 True 4m7s
default │ └─VulnerabilityReport/replicaset-nginx-5fbc65fff-nginx - 3m53s
default └─ReplicaSet/nginx-78449c65d4 - 7h6m
default ├─ConfigAuditReport/replicaset-nginx-78449c65d4 - 7m17s
default └─VulnerabilityReport/replicaset-nginx-78449c65d4-nginx - 6m53s
Finally, when you delete the nginx
Deployment, orphaned security reports will be deleted in the background by the
Kubernetes garbage collection controller.
kubectl delete deploy nginx
kubectl get vuln,configaudit
Result
No resources found in default namespace.
Tip
Use vuln
and configaudit
as short names for vulnerabilityreports
and configauditreports
resources.
Note
You can define the validity period for VulnerabilityReports by setting the duration as the value of the
OPERATOR_VULNERABILITY_SCANNER_REPORT_TTL
environment variable. For example, setting the value to 24h
would delete reports after 24 hours. When a VulnerabilityReport gets deleted Trivy-Operator will automatically
rescan the underlying workload. Assuming that the vulnerability scanner has updated its vulnerability database,
new VulnerabilityReports will contain the latest vulnerabilities.
Infrastructure Scanning¶
The operator discovers also Kubernetes nodes and runs CIS Kubernetes Benchmark checks on each of them. The results are stored as CISKubeBenchReport objects. In other words, for a cluster with 3 nodes the operator will eventually create 3 benchmark reports:
kubectl get node
Result
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready master 3h27m v1.18.8
kind-worker Ready <none> 3h26m v1.18.8
kind-worker2 Ready <none> 3h26m v1.18.8
kubectl get ciskubebenchreports -o wide
Result
NAME SCANNER AGE FAIL WARN INFO PASS
kind-control-plane kube-bench 8s 12 40 0 70
kind-worker kube-bench 9s 2 27 0 18
kind-worker2 kube-bench 9s 2 27 0 18
Notice that each CISKubeBenchReport is named after a node and is controlled by that node to inherit its life cycle:
kubectl tree node kind-control-plane -A
Result
NAMESPACE NAME READY REASON AGE
Node/kind-control-plane True KubeletReady 48m
├─CISKubeBenchReport/kind-control-plane - 44m
├─CSINode/kind-control-plane - 48m
kube-node-lease ├─Lease/kind-control-plane - 48m
kube-system ├─Pod/etcd-kind-control-plane True 48m
kube-system ├─Pod/kube-apiserver-kind-control-plane True 48m
kube-system ├─Pod/kube-controller-manager-kind-control-plane True 48m
kube-system └─Pod/kube-scheduler-kind-control-plane True 48m
What's Next?¶
- Find out how the operator scans workloads that use container images from Private Registries.
- By default, the operator uses Trivy as Vulnerability Scanner and Polaris as Configuration Checker, but you can choose other tools that are integrated with Trivy-Operator or even implement you own plugin.