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

add a doc for prefetchfiles-nri-plugin #524

Closed
wants to merge 5 commits into from

Conversation

billie60
Copy link
Contributor

This document mainly introduces the early configuration and usage of prefetch-nri-plugin.

@@ -0,0 +1,156 @@
# User self-defined nydus image files prefetch
To improve the flexibility of nydus image files prefetch, for the k8s scenario, we can specify a prefetch files list when create a nydus daemon. The prefetch files list is user self-defined. Nydus-snapshotter has implemented a containerd NRI plugin to transmit the path of prefetch files list to nydus-snapshotter. The prefetch plugin requires NRI 2.0, which is available in containerd (>=v1.7.0). The prefetch plugin subscribes pod creation event, fetches the path of prefetch files list and forwards it to nydus-snapshotter. Then when `nydusd` starts, it will pull the files defined in the prefetch files list through lazy loading. This allows the pull of the prefetch files to be done during container creation rather than image convert, improving the flexibility of file prefetching.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean "the list of prefetch file paths"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your comment. What is saved in the prefetch file is indeed the list of prefetch file paths. But the --prefetch-files parameter of nydusd needs to specify a path that points to the file containing the prefetch files (maybe a txt file). So I mean the path of prefetch files list, which is the actual parameter of --prefetch-files

## Workflow

1. Add information such as image reference and prefetch list path to annotations in pod configuration file.
2. Run the prefetch plugin to monitoring RunPodSandbox events.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad syntax, should be "to monitor"


1. Add information such as image reference and prefetch list path to annotations in pod configuration file.
2. Run the prefetch plugin to monitoring RunPodSandbox events.
3. The prefetch plugin fetches image reference and prefetch files path and forwards them to nydus-snapshotter.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

file paths

3. The prefetch plugin fetches image reference and prefetch files path and forwards them to nydus-snapshotter.
4. Nydus-snapshotter specifies the prefetch list when starting nydus daemon.
5. Nydusd completes the mounting of the nydus image.
<!-- 4. Run the prefetch plugin to fetch those information and forward them to nydus-snapshotter when the RunPodSandbox event occurs. -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this line for?




Note that the naming of keys in annotations is fixed, and the values in annotations is user self-defined.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are user self-defined.



Note that the naming of keys in annotations is fixed, and the values in annotations is user self-defined.
After create a pod, image reference and path of prefetch list will received by nydus-snapshotter.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After creating a pod

annotations:
containerd.io/nydus-prefetch: |
[
{"image": "dockerhub.kubekey.local/dfns/wordpress:nydus_latest", "prefetch": "/path/to/wordpress_prefetch.txt"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Um. If the value is a file path, I am concerning how can we distribute the file to each K8s node?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add an comment: specify the prefetch value with an URL is coming. 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THANKS very much! Other comments have been modified, and I will also correct this comment in the next version commit

socket_address = "/run/containerd-nydus/system.sock"
EOF
```
Also, when manually starting the prefetch NRI plugin, the socket address can also be modified through the command line parameter `socket-addr`. Note that the priority of configuration file parameter passing is higher than that of command line parameter passing.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps command line parameters have higher priority would make more sense.

```
Add a prefetch configuration file to specify the correct socket address. Note that this configuration file is designed for starting the NRI plugin in `pre-connection` mode. In this mode, the NRI plugin and containerd will start simultaneously.
```console
sudo tee /etc/nydus/prefetchConfig.toml <<- EOF
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is /etc/nydus/prefetchConfig.toml the right path? In default, containerd read NRI's configuration file from /etc/nri/conf.d.

annotations:
containerd.io/nydus-prefetch: |
[
{"image": "dockerhub.kubekey.local/dfns/wordpress:nydus_latest", "prefetch": "/path/to/wordpress_prefetch.txt"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add an comment: specify the prefetch value with an URL is coming. 😉

@billie60 billie60 force-pushed the prefetchnri-doc branch 4 times, most recently from e2f26c6 to 87b8fa0 Compare September 25, 2023 14:24
@imeoer
Copy link
Collaborator

imeoer commented Sep 26, 2023

The .idea directory should be removed.

socket_address = "/run/containerd-nydus/system.sock"
# The events that containerd subscribes to.
# Do not change this element.
events = ["RunPodSandbox"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to export this entry.

}
} else {
globalSocket = flags.Args.SocketAddress
if globalSocket == "" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should verify if the flags.Args.Config.SocketAddr is nil.

if flags.Args.Config.SocketAddr != nil {
   globalSocket = flags.Args.Config.SocketAddr
} else {
   globalSocket = defaultSystemControllerAddress
}

nydusPrefetchAnnotation = "containerd.io/nydus-prefetch"
)

type PluginConfig struct {
SocketAddr string `toml:"socket_address"`
Events []string `toml:"events"`
Copy link
Member

@sctb512 sctb512 Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove it because it is unused. The defaultEvents is enough.

@billie60 billie60 force-pushed the prefetchnri-doc branch 8 times, most recently from 5ac4580 to 0bae30a Compare September 30, 2023 12:20
@billie60 billie60 force-pushed the prefetchnri-doc branch 6 times, most recently from 21cb39c to d585766 Compare October 24, 2023 08:25
Copy link
Member

@sctb512 sctb512 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Others, LGTM

@@ -82,7 +82,8 @@ jobs:
- name: Build
run: |
# Download nydus components
NYDUS_VER=v$(curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -s "https://api.github.com/repos/dragonflyoss/image-service/releases/latest" | jq -r .tag_name | sed 's/^v//')
# NYDUS_VER=v$(curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -s "https://api.github.com/repos/dragonflyoss/image-service/releases/latest" | jq -r .tag_name | sed 's/^v//')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the dead code.

@@ -62,8 +64,8 @@ func buildFlags(args *PluginArgs) []cli.Flag {
&cli.StringFlag{
Name: "socket-addr",
Value: defaultSystemControllerAddress,
Usage: "unix domain socket address. If defined in the configuration file, there is no need to add ",
Destination: &args.SocketAddress,
Usage: "unix domain socket address.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we need more information. UNIX domain socket address for connection to the nydus-snapshotter API.?

} else {
globalSocket = flags.Args.SocketAddress
globalSocket = defaultSystemControllerAddress
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to set defaultSystemControllerAddress for globalSocket because we have specify defaultSystemControllerAddress as the default value for SocketAddr flag. IOW, the flags.Args.Config.SocketAddr must not be nil.

```console
sudo systemctl restart containerd
```
If you want to start the plugin using `pre-connection` mode, that is, `disableConnections: true`. You need to write a configuration file and place the plugin's binary file and configuration file in the correct directories. Here is an example of configuration file:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pre-connection mode is not related to disableConnections, they can work at the same time.


crictl runp pod.yaml
```
The files that require prefetching are written in a URL, and `nydus-snapshoter` will read the prefetch list based on the URL address and transfer it to a local text file. The specific content of the prefetch files can be customized by the user.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The list of files to be prefetched is written in a URL, and `nydus-snapshoter` will read the prefetch list based on the URL address and transfer it to a local file.

@@ -0,0 +1,3 @@
# unix domain socket address
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to create a new script for integration?
Morever, entrypoint.sh is used as the ENTRYPOINT of image, but this script integration/prefetch.sh is not used by make integrate command.

)

const prefetchlistPath string = "/opt/PrefetchFiles"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this configurable?

defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
errMsg := fmt.Sprintf("HTTP response status code is not 200 OK: %s", resp.Status)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"failed to GET %s, response status $v", url, resp.Status

tokenizer := html.NewTokenizer(resp.Body)
inBody := false

for {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why we need this loop. May have a more concise implementation?
Could you take a look at this? cc @imeoer

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can't assume the server side returns such html format.

@billie60 billie60 force-pushed the prefetchnri-doc branch 5 times, most recently from 03a0a2e to 1589530 Compare October 31, 2023 08:49
@codecov
Copy link

codecov bot commented Oct 31, 2023

Codecov Report

Attention: 20 lines in your changes are missing coverage. Please review.

Comparison is base (47d4311) 33.52% compared to head (c822caa) 33.49%.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #524      +/-   ##
==========================================
- Coverage   33.52%   33.49%   -0.04%     
==========================================
  Files          65       65              
  Lines        8287     8298      +11     
==========================================
+ Hits         2778     2779       +1     
- Misses       5194     5204      +10     
  Partials      315      315              
Files Coverage Δ
pkg/daemon/daemon.go 0.00% <ø> (ø)
pkg/system/system.go 4.79% <0.00%> (ø)
config/global.go 23.21% <33.33%> (+0.27%) ⬆️
pkg/manager/daemon_adaptor.go 0.00% <0.00%> (ø)
pkg/manager/manager.go 0.00% <0.00%> (ø)
pkg/daemon/config.go 0.00% <0.00%> (ø)

@@ -0,0 +1,127 @@
# User self-defined nydus image files prefetch
To improve the flexibility of nydus image files prefetch, for the k8s scenario, we can specify a prefetch files list when create a nydus daemon. The prefetch files list is user self-defined. Nydus-snapshotter has implemented a containerd NRI plugin to transmit the path of prefetch files list to nydus-snapshotter. The prefetch plugin requires NRI 2.0, which is available in containerd (>=v1.7.0). The prefetch plugin subscribes pod creation event, obtains the URL address containing the content of the files need to be prefetched, and forwards it to `nydus-snapshotter`. The `nydus-snapshotter` reads the data through the URL and stores it locally. Then when `nydusd` starts, it will pull the files defined in the prefetch files list through lazy loading. This allows the pull of the prefetch files to be done during container creation rather than image convert, improving the flexibility of file prefetching.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First should explain why we need the prefetch, then say the flexibility of prefetch on runtime.


## Requirements

- [NRI 2.0](https://github.com/containerd/nri): Which has been integrated into containerd since [v1.7.0](https://github.com/containerd/containerd/tree/v1.7.0-beta.1).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be https://github.com/containerd/containerd/tree/v1.7.0 ?





Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove multiple spaces before this.

log_directory: /tmp
annotations:
containerd.io/nydus-prefetch: |
[
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Format it:

[
    {
        "image": "ghcr.io/dragonflyoss/image-service/wordpress:nydus-nightly-v6",
        "prefetch": "http://example.com/api/v1/resource/wordpress",
    }
]

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the annotation work with multiple line value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, if there are multiple images and prefetchlists in annotations, the code works correctly.

go.mod Outdated
github.com/godbus/dbus/v5 v5.1.0 // indirect
)

require github.com/freddierice/go-losetup v0.0.0-20220711213114-2a14873012db
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please merge require section.

runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line here.

"net/http"
)

func wordpress_prefetchlist(w http.ResponseWriter, req *http.Request) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getWordpressPrefetchList

fmt.Fprintf(w, responseText)
}

func tomcat_prefetchlist(w http.ResponseWriter, req *http.Request) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getTomcatPrefetchList

@@ -63,6 +63,9 @@ address = ":9110"
[remote]
convert_vpc_registry = false

[prefetch]
dir = "/opt/prefetch"
Copy link
Collaborator

@imeoer imeoer Nov 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we remove the useless prefetch list file in this dir?

type prefetchlist struct {
PrefetchFiles []string `json:"prefetchFiles"`
}

Copy link
Collaborator

@imeoer imeoer Nov 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type prefetchList struct {
	Files []string `json:"files"`
}

p.prefetchMap[image] = prefetchfiles
}

log.L.Infof("received prefetch list from nri plugin: %v ", p.prefetchMap)
return nil
}

// Obtain the prefetch files through the URL and transfer them to local files().
func (p *prefetchInfo) getprefetchConfigFile(url, image string) (string, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getPrefetchListPath

@billie60 billie60 force-pushed the prefetchnri-doc branch 5 times, most recently from 392de38 to eb73d5d Compare November 15, 2023 09:01
@billie60 billie60 force-pushed the prefetchnri-doc branch 5 times, most recently from 34808aa to 9d3ff61 Compare December 22, 2023 07:51
Signed-off-by: billie60 <[email protected]>
1. specify the prefetch value with an URL
2. Modify the reading mode of configuration file
3. add prefetchlist path in config.toml and so on

Signed-off-by: billie60 <[email protected]>
Signed-off-by: billie60 <[email protected]>

crictl 1.29.0 cni v1.4.0

dockerfile all newest version
@billie60 billie60 force-pushed the prefetchnri-doc branch 2 times, most recently from a418ce6 to c822caa Compare December 29, 2023 04:48
@billie60 billie60 closed this Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants