Showing posts with label k8s. Show all posts
Showing posts with label k8s. Show all posts

Kyverno


 Kyverno Policy

- 2 types: Policy and ClusterPolicy

- Multiple Rules

- Match / Exclude

-- Match resources

kind is mandatory. names, namespaces, operations, selector are optional. 

Wildcards * supported in kinds, names, namespaces

All are AND condition. 

Any means OR condition

We can mention based on who created

exclude:

any:
- clusterRoles:
- cluster-admin
- subjects:
- kind: User
name: John

match AND exclude

exclude must be a subset of match

- Action

1. Validate ( allow / deny )

2. Mutate

3. Generate new K8s object

4. Verify image (Cosign/Sigstore)

- Enforce / Audit

* It uses JAMESPath

- Filter JSON

# Returns a list of container objects that match the condition
{{ request.object.spec.containers[?starts_with(image, 'nginx')] }}

validate:

message: "Nginx images are not allowed!"
deny:
conditions:
all:
# Filter the list. Use length() to count.
# If count > 0, it means a violation exists -> Block.
- key: "{{ request.object.spec.containers[?starts_with(image, 'nginx')] | length(@) }}"
operator: GreaterThan
value: 0

- pipe

Used to extract a specific field from a complex object into a flat list.

# Input: List of container objects
# Output: ["nginx:latest", "redis:alpine", "busybox"]
key: "{{ request.object.spec.containers[].image }}"

kyverno jp query -i object.json 'spec.containers[].name'

Combo (Filter + Pipe): “Get the containerPort of the container named ‘app’”

 request.object.spec.containers[?name == 'app'].ports[].containerPort

You want to find the names of all volumes that are of type emptyDir.

spec.volumes[?emptyDir != null].name

kyverno jp query -i object.json "spec.volumes[?emptyDir != null]"

- null handling

Risk: {{ request.object.metadata.labels.team }} (If null -> Error).

Safe: {{ request.object.metadata.labels.team || '' }} (If null -> treat as empty string).

- The length function

Example: “A Pod must not have more than 3 containers.”

validate:
deny:
conditions:
all:
- key: "{{ request.object.spec.containers | length(@) }}"
operator: GreaterThan
value: 3

- if / else 

- sum

- contain means exist : contains(request.object.metadata.labels, 'production')

advance mutate foreach

mutate:

foreach:
- list: "request.object.spec.containers"
patchStrategicMerge:
spec:
containers:
- name: "{{ element.name }}"
securityContext:
readOnlyRootFilesystem: true

* Aut-Gen: If rule for pod then automatically generate rules for Deployment, StatefulSet, DaemonSet, etc.

https://release-1-8-0.kyverno.io/docs/writing-policies/autogen/

Generate rule has synchronize flag

synchronize: true: Kyverno complete managed lifecycle

synchronize: false: Kyverno created for the first time then user can edit it manually without getting revert back like synchronize: true

* request.object is the incoming resource configuration (the new state) that is being submitted to Kubernetes API server

Documentation: https://kyverno.io/docs/policy-types/cluster-policy/variables/ 

  # -------------------------------------------------------------

  # ACTION: If Kyverno is dead, just let the request go through.

  # -------------------------------------------------------------

  failurePolicy: Ignore # or Fail


PolicyReport

PolicyReport stores the results of those rules.

The PolicyReport is essentially a “Health Check Report Card” for your Kubernetes resources.

Its main goal is Observability & Auditing.

It provides summary and then detail about all failures. For Example

apiVersion: wgpolicyk8s.io/v1alpha2
kind: PolicyReport
metadata:
name: polr-ns-default
namespace: default # It lives next to the Pod, not at the cluster level
labels:
app.kubernetes.io/managed-by: kyverno
summary:
pass: 0
fail: 1
warn: 0
error: 0
skip: 0
results:
- policy: require-labels # The name of the ClusterPolicy responsible
rule: check-for-team-label # The specific rule name
category: Best Practices
severity: medium
result: fail # The outcome (fail, pass, warn, error, skip)
message: "Validation error: label 'team' is required"
source: kyverno
resources: # The specific object that failed
- apiVersion: v1
kind: Pod
name: nginx
namespace: default
uid: a1b2c3d4-e5f6...

* Background scan never delete resource even with enforce mode

* For background scan following variable are not relevant

request.userInfo.*

request.operation

request.dryRun

serviceAccountName in admission context

Document: https://kyverno.io/docs/policy-reports/background/

* Cleanup policy delete pods

https://kyverno.io/docs/policy-types/cleanup-policy/

Kyverno CLI

* for given resource, policy is pass or fail

kyverno apply policy.yaml --resource pod.yaml

* test JAMESPath expression against JSON

kyverno jp query -i object.json 'metadata.labels'

* Check policy YAML is written correctly or not

kyverno validate policy.yaml

External Data Source

Purpose: It allows you to load data from outside into a variable before the rule logic (validate/mutate) runs.

In order to consume data from a ConfigMap in a rule, a context is required... The context data can then be referenced in the policy rule using JMESPath notation.

Kyverno supports 3 main data sources in context:

1. Kubernetes Resources (via API Call): Look up existing data in the cluster (e.g., ConfigMaps, Secrets, Services).

2. External APIs: Make an HTTP call to a service outside the cluster.

3. Image Registry: Fetch metadata about a container image (e.g., image size, architecture).

verifyImages:
- imageReferences:
- "ghcr.io/myorg/*"
attestors:
- entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

https://main.kyverno.io/docs/policy-types/cluster-policy/external-data-sources/

Kyverno Mutate — JSON Patch

the standard patchStrategicMerge merges YAMLs together.

patchesJson6902 is a mutation method specific operations (RFC 6902 standard) to tell Kyverno exactly how to change the data.

Usage: 

* Removing a field (impossible with standard merge).

* Adding an item to a specific position in a list (arrays).

* Replacing a value entirely without merging.

It follows the JSON Patch format:

* op: The action (add, remove, replace).

* path: The location of the field (e.g., /metadata/labels/mytag).

* value: The data to put there.

Example: “Add a sidecar container”

https://main.kyverno.io/docs/policy-types/cluster-policy/mutate/#rfc-6902-jsonpatch

TTL Default of Certification in Kyverno:

https://pkg.go.dev/github.com/kyverno/kyverno/pkg/tls

const (

    CAValidityDuration = 365 * 24 * time.Hour      // 365 days

    TLSValidityDuration = 150 * 24 * time.Hour     // 150 days

    CertRenewalInterval = 12 * time.Hour           // 12 hours

)

https://www.udemy.com/course/complete-certified-kyverno-associate-kca-exam-prep/

https://medium.com/@kienlt.qn/prepare-for-the-kyverno-certified-associate-kca-exam-c144906f9bc2

Concurrent Policies Generation Number Default!

PolicyException CRD

CEL

LLMOps


For AI application, we need automation of 

1. Data preparation
2. model tuning
3. Deployment
4. Maintenance and 
5. Monitoring

  • Managing Dependency adds complexity. 

E2E workflow for LLM based application. 

MLOps framework

1. data ingestion

2. data validation

3. data transformation

4. model

5. model analysis

6. serving model

7. logging. 

LLM System Design

boarder design of E2E app including front end, back end, data engineering etc. 

Chain multiple LLMs together

* Grounding : provides additional information/fact with prompt to LLM. 

* Track History. how it works past. 

LLM App

User input->Preprocessing->grounding->prompt goes to LLM model->LLM Response->Grounding->Post processing + Responsible AI->Final output to user.

Model Customization

1. Data Prep

2. Model Tuning

3. Evaluate

It is iterative process

LLMOps Pipeline (Simplified)

1. Data Preparation and versioning (for training data)

2. Supervised tuning (pipeline) 

3. Artifact = config and workflow : are generated. 

- config = config for workflow

E.g. 

Which data set to use

- Workflow = steps 

4. Pipeline execution

5. deploy LLM 

6. Prompting and predictions

7. Responsible AI

Orchestration = 1 + 2 . Orchestration : What is first, then next step and further next step. sequence of step assurance. 

Automation = 4 + 5

Fine Tuning Data Model using Instructions (Hint)

1. rules

2. step by step

3. procedure

4. example

File formats

1. JSONL: JSON Line. Human readable. For small and medium size dataset. 

2. TFRecord 

3. Parquet for large and complex dataset. 

MLOps Workflow for LLM

1. Apache Airflow

2. KubeFlow

DSL = Domain Specific Language

Decorator 

@dls.component

@dls.pipeline

Next compiler will generate YAML file for pipeline

YAML file has

- components

- deploymentSpec

Pipeline can be run on

- K8s

- Vertex AI pipeline execute pipeline in serverless enviornment

PipelineJob takes inputs

1. Template Path: pipline.yaml

2. Display name

3. Parameters

4. Location: Data center

5. pipeline root: temp file location

Open Source Pipeline

https://us-kfp.pkg.dev/ml-pipeline/large-language-model-pipelines/tune-large-model/v2.0.0

Deployment

Batch and REST

1. Batch. E.g. customer review. Not real time. 

2. REST API e.g. chat. More like teal time library. 

* pprint is library to format 

LLM provides output and 'safetyAttributes'

- blocked

* We can find citation also from output of LLM

===========

vertexAI SDK

https://cloud.google.com/vertex-ai

BigQuery 

https://cloud.google.com/bigquery

sklearn

To decide data 80-20% for training and evaluation. 

Building AI/ML apps in Python with BigQuery DataFrames | Google Cloud Blog

===========

K8s GW API


Examples: 

Istio, Kong, Envoy , Gluee , Trafeik, kgateway, Contour, NGINX, Kong Gateway and many more as per https://gateway-api.sigs.k8s.io/implementations/#gateway-controller-implementation-status

Protocols: gRPC, HTTP/2, and WebSockets

The structure of a Kubernetes Custom Resource Definition (CRD) or manifest file is referred to as an API. This is because it refers to the structure of the API in the Kubernetes control plane

Migration from ingress https://gateway-api.sigs.k8s.io/guides/migrating-from-ingress/#migrating-from-ingress

extension points

ingress has 2 extension points

1. annotations

2. resource end point


primary extension points in GW API:


1. External references


1.1 HTTP Route Filter

1.2 Backend Object Reference

1.3 Secret Object Reference

Here GW API reference 'external reference'

2. Custom implementations


e.g. The RegularExpression type of the 'HTTP Path Match'


3. Policies

A "Policy Attachment" is a specific type of metaresource

Here, Policy reference 'GW API'

  • GW API is not API GW
  • GAMMA (Gateway API for Mesh Management and Administration) initiative
  • A 'waypoint proxy' is a proxy server deployed inside the mesh for E-W traffic. It can be (1) per namespace level destination services (2) few service(s) within a namespace as destination (3) destination services from multiple namespaces. 
3.1 Traffic Policy
* It has transformation field to manipulate header and payload for request and response both. It is based on inja language

* It has ai field for prompt enrichment. 

  ai:
    promptEnrichment:
      prepend:
      - role: SYSTEM
        content: "Parse the unstructured text into CSV format."

1. GatewayClass 

- It is at cluster level. so no namespace

- Annotations at GatewayClassfor vendor specific

- It defines controller capabilities

2. Gateway

- Each Gateway defines one or more listeners, which are the ingress points to the cluster

- You can control which services can be connected to this listener (allowedRoutes) by way of their namespace — this defaults to the same namespace as the Gateway 

- Advanced featues like 

-- request mirroring, 

-- direct response injection, 

-- and fine-grained traffic metrics

-- Traffic spilt

- In Istio APIs, a Gateway configures an existing gateway Deployment/Service that has been deployed. In the Gateway APIs, the Gateway resource both configures and deploys a gateway

- one can attach HPA and PodDisuptionBudget to gateway deployment. 

3. HTTP Route: 

- any combinations of hostname, path, header values, HTTP method and query parameters.

  • Paths (e.g., /headers, /status/*)
  • Headers (e.g., User-Agent: Mobile)
  • Query Parameters (e.g., ?version=beta)
  • Methods (e.g., GET, POST)
You can also define multiple matching criteria and even combine them with an AND or OR operator.

- hostname (optional) at HTTP route shall match with hostname at Gateway->Listener->hostname

- A definition of the Gateway to use (in ParentRefs), is referenced by name and namespace

- The backendRefs that defines the service to route the request to for this match

- advanced pattern matching and filtering on arbitrary headers as well as paths.

1. RequestRedirect : E.g. Redirect HTTP traffic to HTTPS

2. URLRewrite

3. <Request|Response>HeaderModifier

4. RequestMirror

5. CORS

6. ExtensionRef for custom filter. E.g. DirectResponse

    filters:

    - type: ExtensionRef

      extensionRef:

       name: direct-response

       group: gateway.kgateway.dev

       kind: DirectResponse

- In the Istio VirtualService, all protocols are configured within a single resource. In the Gateway APIs, each protocol type has its own resource, such as HTTPRoute and TCPRoute.

- Traffic splitting is done by specifying multiple backendRef, with weight

- timeout, retry, sessionPersistence Session persistence, (= sticky sessions or strong session affinity), ensures that a client's requests are consistently routed to the same backend instance for the duration of a session. based on cookie or a header

- Route and Gateway can be in different namespace. If Gateway is defined with

    allowedRoutes:

      namespaces:

        from: Same

then Route and Gateway shall be in same namespace. We can have group of namespaces with label selector and specify those namespace using label at Gatway resource. 

    allowedRoutes:

      namespaces:

        from: Selector

        selector:

          matchLabels:

            self-serve-ingress: "true"

* 4. TLS Route

5. GRPCRoute

* 6. TCPRoute

* not v1, GA

Details: https://gateway-api.sigs.k8s.io/reference/spec/


If you are using a service mesh, it would be highly desirable to use the same API resources to configure both ingress traffic routing and internal traffic, similar to the way Istio uses VirtualService to configure route rules for both. Fortunately, the Kubernetes Gateway API is working to add this support. Although not as mature as the Gateway API for ingress traffic, an effort known as the Gateway API for Mesh Management and Administration (GAMMA) initiative is underway to make this a reality and Istio intends to make Gateway API the default API for all of its traffic management in the future.

https://gateway-api.sigs.k8s.io/mesh/


Gateway controller is for North South traffic. mesh controller is for East West traffic

7. ReferenceGrant: for cross-namespace reference. 

8. Inference Extension

K8s offers following mechanisms to optimize GPU usage, 

- time slicing, 

- Multi-Instance GPU (MIG) partitioning, 

- virtual GPUs, and 

- NVIDIA MPS 

for concurrent processing.

Effective GPU utilization means

- hardware allocation; 

- how inference requests are routed across model-serving instances. 

- how inference requests are load-balanced across model-serving instances. 

Simple load-balancing strategies often fall short in handling AI workloads effectively, leading to suboptimal GPU usage and increased latency.

Inference requests V/s traditional web traffic

- It often takes much longer to process, sometimes several seconds (or even minutes!) rather than milliseconds, 

- It has significantly larger payloads (ie, with RAG, multi-turn chats, etc). So a single request can consume an entire GPU, So making scheduling decisions far more impactful than those for standard API workloads. So, these requests need to queue up while others are being processed.

AI Models are stateful

- They maintain in-memory caches, such as KV storage for prompt tokens,

- They load fine tuned adapters like LoRA to customize response for specific user/organisation. 

So routing decisions are based on

- current state (in-memory caches, adapters)

- available memory, and 

- request queue depth.

So Inference aware routing through

8.1 Inference Model

- maps user facing model name to backend model

- traffic splitting between fine-tuned adapaters

- Priority based on real time interaction OR best-effort batch job

8.2 Inference Pool

- It is for platform operators managing model-serving infrastructure.

- a group of model-serving instances 

- specialized backend service for AI workloads.

- It manages

-- inference-aware endpoint selection, 

-- intelligent routing decisions based on real-time metrics such as 

--- request queue depth and 

--- GPU memory availability.

* Inference Pool is mapped with HTTP Route->backendRefs

* Inference Model has poolRef to link with Inference Pool

Inference Pool has extensionRef (EPP = Endpoint picker) . If name for Inference Pool is xyz then extensionRef is "xyz-endpoint-picker" It is similar to K8s service, as it also has selector and target port

9. DirectResponse

10. Backend

For external endpoint

Ref: https://tetrate.io/blog/kubernetes-envoy-gateway-extensions