./nsenter.sh -n d8-virtualization -p cdi-apiserver-7477c5f5c8-xx7r6 -x dev-rnd. -- tshark -q -z conv,tcp
Last active
February 19, 2025 15:35
-
-
Save fl64/bf0f90ac7ae9103be5771e8bc55f7963 to your computer and use it in GitHub Desktop.
nsenter.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Function to display usage instructions | |
usage() { | |
echo "Usage: nsenter.sh -n|--namespace <namespace> -p|--pod <pod-name> [-c|--container <container-name>] [-t|--nsenter-namespaces <namespaces>] [-u|--ssh-user <user>] [-h|--ssh-host <host>] [-x|--node-name-prefix <prefix>] -- <command> [args...]" | |
echo "Options:" | |
echo " -n, --namespace Namespace of the pod" | |
echo " -p, --pod Name of the pod" | |
echo " -c, --container Name of the container (optional; default is the first container)" | |
echo " -t, --nsenter-namespaces Namespaces for nsenter (optional; overrides defaults, e.g., 'mnt,uts') net namespace is used by deafult" | |
echo " -u, --ssh-user SSH username (optional)" | |
echo " -h, --ssh-host SSH host override (optional; default is node name)" | |
echo " -x, --node-name-prefix Node name prefix (optional)" | |
echo " -- Command and arguments to execute inside the container" | |
echo "Usage example:" | |
echo "./nsenter.sh -n d8-virtualization -p cdi-apiserver-7477c5f5c8-xx7r6 -x dev-rnd. tshark -i any -q -z conv,tcp -a duration:10" | |
exit 1 | |
} | |
# Parse named arguments | |
NAMESPACE="" | |
POD_NAME="" | |
CONTAINER_NAME="" | |
NSENTER_NAMESPACES="" # Optional additional namespaces for nsenter | |
SSH_USER="" # Optional SSH username | |
SSH_HOST_OVERRIDE="" # Optional SSH host override | |
NODE_NAME_PREFIX="" # Optional node name prefix | |
COMMAND="" | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
-n|--namespace) | |
NAMESPACE="$2" | |
shift 2 | |
;; | |
-p|--pod) | |
POD_NAME="$2" | |
shift 2 | |
;; | |
-c|--container) | |
CONTAINER_NAME="$2" | |
shift 2 | |
;; | |
-t|--nsenter-namespaces) | |
NSENTER_NAMESPACES="$2" | |
shift 2 | |
;; | |
-u|--ssh-user) | |
SSH_USER="$2" | |
shift 2 | |
;; | |
-h|--ssh-host) | |
SSH_HOST_OVERRIDE="$2" | |
shift 2 | |
;; | |
-x|--node-name-prefix) | |
NODE_NAME_PREFIX="$2" | |
shift 2 | |
;; | |
--) | |
shift | |
COMMAND="$@" | |
break | |
;; | |
*) | |
echo "Unknown option: $1" | |
usage | |
;; | |
esac | |
done | |
# Validate required parameters | |
if [ -z "$NAMESPACE" ] || [ -z "$POD_NAME" ] || [ -z "$COMMAND" ]; then | |
echo "Error: Missing required parameters." | |
usage | |
fi | |
# If container name is not provided, use the first container in the pod | |
if [ -z "$CONTAINER_NAME" ]; then | |
CONTAINER_INFO=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath='{.spec.containers[0].name}') | |
if [ -z "$CONTAINER_INFO" ]; then | |
echo "Error: Unable to determine the first container in the pod $POD_NAME." | |
exit 1 | |
fi | |
CONTAINER_NAME="$CONTAINER_INFO" | |
fi | |
# Get pod information | |
POD_INFO=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o json) | |
if [ $? -ne 0 ]; then | |
echo "Error: Failed to retrieve information about pod $POD_NAME." | |
exit 1 | |
fi | |
# Extract NodeName from pod information | |
NODE_NAME=$(echo "$POD_INFO" | jq -r '.spec.nodeName') | |
if [ "$NODE_NAME" == "null" ]; then | |
echo "Error: Unable to determine the node for pod $POD_NAME." | |
exit 1 | |
fi | |
# Extract ContainerID from pod information | |
CONTAINER_ID=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath="{.status.containerStatuses[?(@.name=='$CONTAINER_NAME')].containerID}" | sed 's/containerd:\/\/\(.*\)/\1/') | |
if [ -z "$CONTAINER_ID" ]; then | |
echo "Error: Unable to determine the ContainerID for container $CONTAINER_NAME." | |
exit 1 | |
fi | |
# Determine SSH connection details | |
SSH_HOST=${SSH_HOST_OVERRIDE:-"${NODE_NAME_PREFIX}${NODE_NAME}"} # Use override or default to node name | |
# Build nsenter command with optional namespaces | |
NSENTER_CMD="nsenter --target \$(/opt/deckhouse/bin/crictl inspect --output go-template --template '{{.info.pid}}' $CONTAINER_ID)" | |
# Add namespaces (default or user-provided) | |
if [ -n "$NSENTER_NAMESPACES" ]; then | |
# Use user-provided namespaces (overrides defaults) | |
for ns in $(echo "$NSENTER_NAMESPACES" | tr ',' ' '); do | |
NSENTER_CMD+=" --$ns" | |
done | |
else | |
# Use default namespace (--net) | |
NSENTER_CMD+=" --net " | |
fi | |
# Connect to the node via SSH and execute the command | |
if [ -n "$SSH_USER" ]; then | |
# Use specified SSH user | |
/usr/bin/ssh -t "${SSH_USER}@${SSH_HOST}" "sudo -S bash -c '$NSENTER_CMD $COMMAND'" | |
else | |
# Use SSH without specifying a user | |
/usr/bin/ssh -t "${SSH_HOST}" "sudo -S bash -c '$NSENTER_CMD $COMMAND'" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment