OCI OKE Should Minimize Containers Sharing the Host PID
More Info:
hostPID=true allows a container to view and signal every process on the node, providing trivial paths to escape isolation. Reject pods with hostPID by default in admission policy.
Risk Level
High
Address
Compliance, Security
Compliance Standards
- CIS OKE
Triage and Remediation
- Remediation
Remediation
Using Console
In OKE this setting comes from the Kubernetes pod spec (hostPID: true). There is no single “toggle” in the OCI Console; you remediate by (1) finding the offending workloads and (2) redeploying them without hostPID, and optionally (3) enforcing a policy so it can’t be re‑introduced.
Below are the steps, keeping everything driven from the OCI Console as much as possible.
1. Identify pods using the host PID namespace
- Sign in to the OCI Console.
- Go to Developer Services → Kubernetes Clusters (OKE).
- Select the Compartment, then click your Cluster.
- In the cluster details page, in the left menu, choose Workloads (if available in your console region/version):
- Look at the Pod YAML (or the parent Deployment/DaemonSet/StatefulSet YAML) for suspicious workloads.
- Check each pod’s spec for:
hostPID: true
- If you don’t see it clearly in the GUI, use Cloud Shell from the console:
- Click the Cloud Shell icon (top‑right).
- Configure
kubectlfor your cluster by clicking Access Cluster in the cluster details page and following the on‑screen instructions to download and use the kubeconfig in Cloud Shell. - Then in Cloud Shell run:
kubectl get pods -A -o=jsonpath='{range .items[?(@.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'
- This lists all pods with
hostPID: true.
Note down which namespaces and controller types (Deployment, DaemonSet, Job, etc.) are responsible for those pods.
2. Remove hostPID: true and redeploy
For each offending controller (Deployment/DaemonSet/Job/etc.):
-
In the OCI Console → OKE → your cluster → Workloads:
- Locate the workload (Deployment/DaemonSet/Job) generating the pod.
- Use View YAML to see its manifest.
-
Open Cloud Shell again (from the OCI Console) and edit the manifest via
kubectl:- Export the existing manifest:
kubectl -n <namespace> get deployment <name> -o yaml > deployment.yaml# or: daemonset/statefulset/job as appropriate
- Edit the file in Cloud Shell (e.g., using
vi):- Find any line:
and either remove it (default ishostPID: true
false) or explicitly set:hostPID: false
- Find any line:
- Apply the updated manifest:
kubectl apply -f deployment.yaml
- Export the existing manifest:
-
For controllers you created via Helm or another CI/CD pipeline, update the source (Helm chart values or Git repo) to:
- Remove/disable
hostPID: truein their templates or values. - Redeploy from that system to avoid it being re‑introduced.
- Remove/disable
-
Verify that no pods in the cluster now use the host PID namespace:
kubectl get pods -A -o=jsonpath='{range .items[?(@.spec.hostPID==true)]}{.metadata.namespace}{"\t"}{.metadata.name}{"\n"}{end}'If this returns nothing, the configuration issue is remediated.
3. (Optional but recommended) Enforce a policy so hostPID can’t be used
OKE doesn’t offer a direct “disallow hostPID” switch in the console, but you can enforce it using Kubernetes’ built‑in Pod Security Admission (for clusters on recent Kubernetes versions):
-
In Cloud Shell, label namespaces with a strict Pod Security level that disallows host namespaces (e.g.,
restricted):kubectl label namespace <namespace> pod-security.kubernetes.io/enforce=restricted --overwriteThe
restrictedprofile prohibits host namespace sharing (includinghostPID). -
For system namespaces (like
kube-system) you may need less strict policies; focus on your application namespaces. -
Test by trying to deploy a pod with
hostPID: truein that namespace—it should now be rejected by the API server.
Summary of what you must do in OCI Console–driven flow
- Use OKE cluster page + Cloud Shell to:
- Discover pods with
hostPID: true. - Edit and re‑apply their controller manifests to remove
hostPID. - Optionally label namespaces with
pod-security.kubernetes.io/enforce=restrictedso futurehostPIDusage is blocked.
- Discover pods with
If you share your OKE/Kubernetes version, I can give the exact kubectl commands and sample manifests aligned to that version.
Using CLI
To remediate “Containers sharing the host PID namespace” in OCI OKE, you need to ensure hostPID: false (or absent) in all Pod specs. Using OCI CLI, the flow is:
1. Configure kubectl access via OCI CLI
If you don’t already have kubeconfig for the cluster:
# Variables
REGION="<your-region>" # e.g. us-ashburn-1
CLUSTER_OCID="<your-oke-cluster-ocid>"
KUBECONFIG_PATH="$HOME/.kube/oke-config"
# Generate kubeconfig via OCI CLI
oci ce cluster create-kubeconfig \
--cluster-id "$CLUSTER_OCID" \
--file "$KUBECONFIG_PATH" \
--region "$REGION" \
--token-version 2.0.0 \
--kube-endpoint PUBLIC_ENDPOINT
export KUBECONFIG="$KUBECONFIG_PATH"
2. Find Pods/Workloads using hostPID: true
Check current Pods:
kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.hostPID==true)]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{end}'
Check higher‑level objects (Deployments, DaemonSets, StatefulSets, etc.) that might be creating such Pods:
for kind in deployment daemonset statefulset job cronjob; do
echo "Checking $kind..."
kubectl get $kind --all-namespaces -o yaml | \
yq '.items[] | select(.spec.template.spec.hostPID == true) | .metadata.namespace + " " + .metadata.name'
done
(Assumes yq is installed; if not, you can inspect YAML manually.)
3. Remove / disable hostPID in the workload specs
For each workload identified:
Option A: Patch with kubectl (fastest)
Set hostPID: false on the Pod template:
# Example for a Deployment
NAMESPACE="<namespace>"
DEPLOYMENT_NAME="<deployment-name>"
kubectl patch deployment "$DEPLOYMENT_NAME" -n "$NAMESPACE" \
--type='merge' \
-p '{"spec":{"template":{"spec":{"hostPID":false}}}}'
Similar for other kinds:
# DaemonSet
kubectl patch daemonset "<ds-name>" -n "<namespace>" \
--type='merge' \
-p '{"spec":{"template":{"spec":{"hostPID":false}}}}'
# StatefulSet
kubectl patch statefulset "<sts-name>" -n "<namespace>" \
--type='merge' \
-p '{"spec":{"template":{"spec":{"hostPID":false}}}}'
# Job
kubectl patch job "<job-name>" -n "<namespace>" \
--type='merge' \
-p '{"spec":{"template":{"spec":{"hostPID":false}}}}'
# CronJob (batch/v1)
kubectl patch cronjob "<cronjob-name>" -n "<namespace>" \
--type='merge' \
-p '{"spec":{"jobTemplate":{"spec":{"template":{"spec":{"hostPID":false}}}}}}'
You can drive this fully from OCI CLI by first generating kubeconfig (step 1) and then running these kubectl commands in the same shell.
Option B: Edit manifests and re‑apply
If you manage manifests/Helm charts in Git:
-
In each Pod template, ensure:
spec:hostPID: false # or simply remove hostPID entirely (default is false) -
Re‑deploy:
kubectl apply -f <your-manifest>.yaml
4. Optionally enforce at policy level (prevent future drift)
OKE uses upstream Kubernetes; you can use Pod Security Admission (recommended) or Gatekeeper/OPA. Example (Kubernetes v1.25+ with Pod Security Admission):
Create a namespace label to enforce restricted (which disallows hostPID):
kubectl label namespace <ns> \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
This can also be done after kubeconfig creation from OCI CLI.
5. Verify remediation
Re‑run the check:
kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.hostPID==true)]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{end}'
No output means no Pods are using hostPID: true.
Using Python
In OKE this risk comes from pods that set hostPID: true in the pod spec. You remediate by finding all such workloads and patching them to hostPID: false (or removing the field), then enforcing a policy to prevent new ones.
Below are step‑by‑step instructions and Python examples using the Kubernetes Python client against your OKE cluster.
1. Prereqs
-
Install tools:
pip install kubernetes -
Make sure your
kubectlis already configured for the OKE cluster (e.g. via OCI Console “Access Cluster” instructions).
The Python client will reuse that kubeconfig. -
Verify:
kubectl get nodes
2. Python: Identify all resources using hostPID: true
This script scans common workload types (Pods, Deployments, StatefulSets, DaemonSets, ReplicaSets, Jobs, CronJobs) in all namespaces and prints where hostPID is enabled.
from kubernetes import client, config
from kubernetes.client import ApiException
def has_host_pid(pod_spec):
# pod_spec is a V1PodSpec or None
return bool(pod_spec and getattr(pod_spec, "host_pid", False))
def main():
# Load kubeconfig from ~/.kube/config (default)
config.load_kube_config()
core_v1 = client.CoreV1Api()
apps_v1 = client.AppsV1Api()
batch_v1 = client.BatchV1Api()
batch_v1beta1 = client.BatchV1Api() # for CronJobs in newer clusters
print("=== Scanning Pods ===")
pods = core_v1.list_pod_for_all_namespaces().items
for p in pods:
if has_host_pid(p.spec):
print(f"Pod {p.metadata.namespace}/{p.metadata.name} has hostPID: true")
print("=== Scanning Deployments ===")
deps = apps_v1.list_deployment_for_all_namespaces().items
for d in deps:
if has_host_pid(d.spec.template.spec):
print(f"Deployment {d.metadata.namespace}/{d.metadata.name} has hostPID: true")
print("=== Scanning StatefulSets ===")
ssets = apps_v1.list_stateful_set_for_all_namespaces().items
for s in ssets:
if has_host_pid(s.spec.template.spec):
print(f"StatefulSet {s.metadata.namespace}/{s.metadata.name} has hostPID: true")
print("=== Scanning DaemonSets ===")
dsets = apps_v1.list_daemon_set_for_all_namespaces().items
for ds in dsets:
if has_host_pid(ds.spec.template.spec):
print(f"DaemonSet {ds.metadata.namespace}/{ds.metadata.name} has hostPID: true")
print("=== Scanning ReplicaSets ===")
rsets = apps_v1.list_replica_set_for_all_namespaces().items
for rs in rsets:
if has_host_pid(rs.spec.template.spec):
print(f"ReplicaSet {rs.metadata.namespace}/{rs.metadata.name} has hostPID: true")
print("=== Scanning Jobs ===")
jobs = batch_v1.list_job_for_all_namespaces().items
for j in jobs:
if has_host_pid(j.spec.template.spec):
print(f"Job {j.metadata.namespace}/{j.metadata.name} has hostPID: true")
# CronJobs in newer K8s are batch/v1 CronJob
try:
print("=== Scanning CronJobs ===")
cronjobs = batch_v1.list_cron_job_for_all_namespaces().items
for cj in cronjobs:
if has_host_pid(cj.spec.job_template.spec.template.spec):
print(f"CronJob {cj.metadata.namespace}/{cj.metadata.name} has hostPID: true")
except ApiException as e:
if e.status != 404:
raise
if __name__ == "__main__":
main()
Run this to see all offenders.
3. Python: Remediate by patching hostPID to false
You should ideally fix the original manifests in Git/Helm first. But if you need to remediate live workloads via script, you can patch them like this.
Below is an example for Deployments and StatefulSets (you can extend to other controllers similarly):
from kubernetes import client, config
def main():
config.load_kube_config()
apps_v1 = client.AppsV1Api()
# ---- Patch Deployments ----
deployments = apps_v1.list_deployment_for_all_namespaces().items
for d in deployments:
ns = d.metadata.namespace
name = d.metadata.name
spec = d.spec.template.spec
if spec and getattr(spec, "host_pid", False):
print(f"Patching Deployment {ns}/{name} to hostPID: false")
patch_body = {
"spec": {
"template": {
"spec": {
"hostPID": False
}
}
}
}
apps_v1.patch_namespaced_deployment(name=name, namespace=ns, body=patch_body)
# ---- Patch StatefulSets ----
ssets = apps_v1.list_stateful_set_for_all_namespaces().items
for s in ssets:
ns = s.metadata.namespace
name = s.metadata.name
spec = s.spec.template.spec
if spec and getattr(spec, "host_pid", False):
print(f"Patching StatefulSet {ns}/{name} to hostPID: false")
patch_body = {
"spec": {
"template": {
"spec": {
"hostPID": False
}
}
}
}
apps_v1.patch_namespaced_stateful_set(name=name, namespace=ns, body=patch_body)
if __name__ == "__main__":
main()
You can add similar blocks for:
apps_v1.patch_namespaced_daemon_setapps_v1.patch_namespaced_replica_setbatch_v1.patch_namespaced_jobbatch_v1.patch_namespaced_cron_job- Or patch individual Pods (not usually needed if controlled by a higher-level resource).
4. Prevent new hostPID usage (policy)
For long‑term remediation, you should block hostPID: true at admission time:
- If using Gatekeeper / OPA (or Kyverno), add a policy that denies any pod with
spec.hostPID: true. - Or use Kubernetes Pod Security Admission (PSA) with at least
baseline/restrictedprofiles (which disallow host namespaces).
In OKE, you’d typically:
-
Enable Pod Security Admission in the cluster (if supported by your OKE/K8s version).
-
Set the namespace label, e.g.:
kubectl label namespace <ns> pod-security.kubernetes.io/enforce=restricted
This will prevent future pods from using hostPID.
5. Validate
After the script and/or policy:
- Re-run the scanning script — it should find no
hostPID: true. - Try to deploy a test pod with
hostPID: true; it should be rejected by policy (if configured).
If you share which controllers/resources you’re using (Helm, raw YAML, Operators), I can tailor a minimal Python script that only targets those.
Using Terraform
This setting cannot be configured on the oci_containerengine_cluster (OKE cluster) resource in Terraform; OKE does not expose admission policy / hostPID controls at the cluster resource level.
Rejecting pods with hostPID: true must be done via Kubernetes admission control objects inside the cluster (for example, Pod Security Admission, ValidatingAdmissionPolicy, or a validating webhook such as Gatekeeper/Kyverno), created with kubectl or via a Kubernetes Terraform provider. In the OCI Console you would:
- Get credentials for the OKE cluster and configure
kubectl. - Apply an admission policy (e.g., a ValidatingAdmissionPolicy or webhook) that denies any pod where
spec.hostPID == true.