Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make our kubectl image more useful? #119567

Closed
thockin opened this issue Jul 25, 2023 · 24 comments
Closed

Make our kubectl image more useful? #119567

thockin opened this issue Jul 25, 2023 · 24 comments
Assignees
Labels
kind/feature Categorizes issue or PR as related to a new feature. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. sig/cli Categorizes an issue or PR as relevant to SIG CLI. sig/release Categorizes an issue or PR as relevant to SIG Release.

Comments

@thockin
Copy link
Member

thockin commented Jul 25, 2023

xref #116667 which was "resolved" with #116672
xref #73760
xref #40610

We have the "downward API" which extracts almost exclusively information which is represented as fields on "this pod" and projects either env vars or files on disk. But there's a slow but non-zero trickle of requests to extract info from other places (e.g. "this node"). This is less obviously reasonable because it could turn into a confused-deputy, exposing information that the pod is not actually authorized to know.

In #73760 (comment) (more than 2 years ago!) I suggested people use a sidecar to get and format the info. We have never actually made such a sidecar image, leaving it as an exercise for the reader.

Can / shold we do better?

The existing image (registry.k8s.io/kubernetes/kubectl) seems to serve two purposes:

  1. as a portable CLI when you don't have kubectl installed
  2. as this sidecars

It works for #1, but is not super useful for #2 without some sorts of tools in the image.

How would we feel about either pivoting it or adding a new kubectl-sidecar image and adding a bunch of useful shell tools? E.g.

  • bash
  • grep
  • sed
  • awk
  • head
  • tail
  • jq
  • diff
  • coreutils (mv, ln, cat, sleep, ...)

In short, I think it should be possible for people to write something like:

while true; do
    kubectl get -o json node $THIS_NODE | jq -r '.status.conditions[] | [.type,.status] | @tsv' | grep Ready | cut -f2 > .ready.tmp
    mv -f file.tmp ready
    sleep 10
done

cc @dims since you touched the image before :)

@k8s-ci-robot k8s-ci-robot added needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Jul 25, 2023
@k8s-ci-robot
Copy link
Contributor

This issue is currently awaiting triage.

If a SIG or subproject determines this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@dims dims self-assigned this Jul 25, 2023
@dims
Copy link
Member

dims commented Jul 25, 2023

@thockin yes of course! happy to iterate the existing image, let me find some folks who can help us take care of this image going forward (add/update docs, write up blog posts, evangelize this!)

@rayandas
Copy link
Member

I would love to get involved in this. :)

@Ritikaa96
Copy link
Contributor

/kind feature
/sig release

@k8s-ci-robot k8s-ci-robot added kind/feature Categorizes issue or PR as related to a new feature. sig/release Categorizes an issue or PR as relevant to SIG Release. and removed needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Jul 26, 2023
@Debanitrkl
Copy link
Member

Debanitrkl commented Jul 26, 2023

Happy to contribute to this, need more context, so we are first going to add the shell tools(do we want to list them out first?) as command to kubectl and then release a new kubectl-sidecar image?

@vatsalparekh
Copy link
Contributor

I would like get involved in this too

@dims
Copy link
Member

dims commented Jul 26, 2023

first step is to update the kubectl image with the shell tools listed by @thockin (No to a new image, No to new commands to kubectl for now)
i'd also request folks to write a blog with the possibilities using the kubectl image that will go with k8s 1.28

@thockin
Copy link
Member Author

thockin commented Jul 26, 2023 via email

@dipankardas011
Copy link
Contributor

@thockin, I am unable to understand what changes you proposed, I have used Kubectl but not getting what features are missing

can you explain it? :)

@thockin
Copy link
Member Author

thockin commented Jul 26, 2023 via email

@pbxqdown
Copy link
Contributor

/sig cli

@k8s-ci-robot k8s-ci-robot added the sig/cli Categorizes an issue or PR as relevant to SIG CLI. label Jul 27, 2023
@BenTheElder
Copy link
Member

This sort of image has a large "API" and needs more frequent patching.

I think we should still provide a minimal kubectl image that won't set off everyone's CVE scanners and will pull quickly.

@thockin
Copy link
Member Author

thockin commented Aug 28, 2023

What is the smaller image useful for? The only use case I can see is "I want to run kubectl in a place where I don't have a kubectl binary, but I do have a kubeconfig file". Not impossible but it seems unlikely. It's not useful in a pod except as a one-off (otherwise you need a shell to drive a loop). If it is only for CLI use, the larger image doesn't seem problematic to me.

Help me understand a user-story where this is useful other than "I want to run a sidecar which extract info from API and writes it to a file in a volume" ?

@BenTheElder
Copy link
Member

Help me understand a user-story where this is useful other than "I want to run a sidecar which extract info from API and writes it to a file in a volume" ?

"I don't want to install kubectl when I can run a container" was a driving use-case on the original kubectl image thread IIRC, you can more readily pipe the output to other tools if you're running outside the cluster.

@xmudrii
Copy link
Member

xmudrii commented Aug 28, 2023

I left some opinions in this comment: #119592 (comment)

I think I agree with @thockin about this. My opinion is that we should optimize for user experience here.

@thockin
Copy link
Member Author

thockin commented Aug 28, 2023

"I don't want to install kubectl when I can run a container"

I do accept that use case. That said, we might disagree whether having a shell and tools in the image is important for CLI users. Even if you don't have a local kubectl binary, you probably have grep, but do you have jq? It's less common.

What's the impact of a larger (size and surface) image for CLI users? Not much, I think? Either way, we need such an image and need to keep it patched.

@rayandas
Copy link
Member

As the revert is now merged, I've created another WIP PR to add the necessary utils and the multi arch image.
A TODO is to implement a hack to adjust the multi arch image so that the build passes.

I think one of the possible way is to add a Makefile along with the Kubectl Dockerfile, just like etcd image and force selection of the correct image.

cc: @dims @saschagrunert @xmudrii

@thockin
Copy link
Member Author

thockin commented Aug 31, 2023

Is the debian-base image not a multi-arch manifest?

@rayandas
Copy link
Member

rayandas commented Sep 1, 2023

@thockin It is a multi-arch image, but somehow it's not picking the right image while building for ARM64. These were the failures on master-blocking build-master and master-informing Conformance-EC2-arm64-master.

@thockin
Copy link
Member Author

thockin commented Sep 1, 2023

I build multi-arch git-sync using docker buildx - docker itself thinks it is the other architecture. I don't know how this works in k/k/build any more, but here's how git-sync does it:

make all-container:

ALL_PLATFORMS := linux/amd64 linux/arm linux/arm64 linux/ppc64le linux/s390x
all-container: $(addprefix container-, $(subst /,_, $(ALL_PLATFORMS)))

calls (https://github.com/kubernetes/git-sync/blob/master/Makefile#L164-L192):

container: .container-$(DOTFILE_IMAGE) container-name
.container-$(DOTFILE_IMAGE): bin/$(OS)_$(ARCH)/$(BIN) $(LICENSES) Dockerfile.in .buildx-initialized
	sed                                  \
	    -e 's|{ARG_BIN}|$(BIN)|g'        \
	    -e 's|{ARG_ARCH}|$(ARCH)|g'      \
	    -e 's|{ARG_OS}|$(OS)|g'          \
	    -e 's|{ARG_FROM}|$(BASEIMAGE)|g' \
	    -e 's|{ARG_STAGING}|/staging|g' \
	    Dockerfile.in > .dockerfile-$(OS)_$(ARCH)
	HASH_LICENSES=$$(find $(LICENSES) -type f                    \
	    | xargs md5sum | md5sum | cut -f1 -d' ');                \
	HASH_BINARY=$$(md5sum bin/$(OS)_$(ARCH)/$(BIN)               \
	    | cut -f1 -d' ');                                        \
	FORCE=0;                                                     \
	if [ -z "$(ALLOW_STALE_APT)" ]; then FORCE=$$(date +%s); fi; \
	docker buildx build                                          \
	    --builder git-sync                                       \
	    --build-arg FORCE_REBUILD="$$FORCE"                      \
	    --build-arg HASH_LICENSES="$$HASH_LICENSES"              \
	    --build-arg HASH_BINARY="$$HASH_BINARY"                  \
	    --progress=plain                                         \
	    --load                                                   \
	    --platform "$(OS)/$(ARCH)"                               \
	    --build-arg HTTP_PROXY=$(HTTP_PROXY)                     \
	    --build-arg HTTPS_PROXY=$(HTTPS_PROXY)                   \
	    -t $(IMAGE):$(OS_ARCH_TAG)                               \
	    -f .dockerfile-$(OS)_$(ARCH)                             \
	    .
	docker images -q $(IMAGE):$(OS_ARCH_TAG) > $@

@rayandas
Copy link
Member

rayandas commented Sep 7, 2023

Ah! alright. I should try something like this. Thanks!

@dims dims assigned rayandas and unassigned dims Sep 27, 2023
@mpuckett159
Copy link
Contributor

imo this should really something we have a blog on like "how to do this" rather than a solution we package and ship to people. Everyone has different threat models and security requirements and having something prescriptive like this is a sure fire way to get an unending amount of issues filed for CVEs that we are then on the hook for mitigating, but then we get into dependency management issues too, and down stream users are going to want certain versions of things, other tooling in general, etc, and really the ideal solution (in my mind) is that users have a blueprint for how to accomplish this task so that they are empowered to create what they need.

@thockin
Copy link
Member Author

thockin commented Jan 14, 2024

What is the result here? Did we decide not to do it? A PR was merged and then reverted. I'd like to go back to the problem statement.

There's a slow, but never-ending trickle of user questions that take the form "I need X information from the API in in my pod". Some of those can be satisfied by the downward API or trivial extensions thereof. But some cannot - e.g. cross-object things like "tell me the name of my topmost parent controller resource" would require kubelet to have permissions on a wide swath of types and to take responsibility for watching them all. And we would have to find ways to express all of those in downward API. In short, downward API is really only useful for things that come from the pod resource and even then, only tirivially-formatted things. Anything that requires multi-field, formatting expressions, or logic is just not workable.

The obvious answer is "do it yourself". Use your own pod's ServiceAccount and fetch the information you need. The problem is that this is a non-trivial punt, especially for 3rd party apps.

This proposal was about making a sidecar-oriented image that was appropriate for this use-case.

Are we now saying we don't care to address this?

@thockin
Copy link
Member Author

thockin commented Mar 11, 2024

@thockin thockin closed this as completed Mar 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. sig/cli Categorizes an issue or PR as relevant to SIG CLI. sig/release Categorizes an issue or PR as relevant to SIG Release.
Projects
Archived in project
Development

No branches or pull requests