cotainerd源码阅读——创建使用unix domain socket的grpc server

创建grpc server

cmd\containerd\command\main.go
 1 // App returns a *cli.App instance.
 2 func App() *cli.App {
 3     app := cli.NewApp()
 4     app.Name = "containerd"
 5     ......
 6     app.Action = func(cliContext *cli.Context) error {
 7         ......
 8         // setup the main grpc endpoint
 9         l, err := sys.GetLocalListener(config.GRPC.Address, config.GRPC.UID, config.GRPC.GID)
10         if err != nil {
11             return fmt.Errorf("failed to get listener for main endpoint: %w", err)
12         }
13         serve(ctx, l, server.ServeGRPC)
14         ......
15     }
16     return app
17 }
NewApp creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action.
 

创建unix domain socket

pkg\sys\socket_unix.go
 1 // CreateUnixSocket creates a unix socket and returns the listener
 2 func CreateUnixSocket(path string) (net.Listener, error) {
 3     // BSDs have a 104 limit
 4     if len(path) > 104 {
 5         return nil, fmt.Errorf("%q: unix socket path too long (> 104)", path)
 6     }
 7     if err := os.MkdirAll(filepath.Dir(path), 0660); err != nil {
 8         return nil, err
 9     }
10     if err := unix.Unlink(path); err != nil && !os.IsNotExist(err) {
11         return nil, err
12     }
13     return net.Listen("unix", path)
14 }
15 
16 // GetLocalListener returns a listener out of a unix socket.
17 func GetLocalListener(path string, uid, gid int) (net.Listener, error) {
18     // Ensure parent directory is created
19     if err := mkdirAs(filepath.Dir(path), uid, gid); err != nil {
20         return nil, err
21     }
22 
23     l, err := CreateUnixSocket(path)
24     if err != nil {
25         return l, fmt.Errorf("failed to create unix socket on %s: %w", path, err)
26     }
27 
28     if err := os.Chmod(path, 0660); err != nil {
29         l.Close()
30         return nil, err
31     }
32 
33     if err := os.Chown(path, uid, gid); err != nil {
34         l.Close()
35         return nil, err
36     }
37 
38     return l, nil
39 }
 

使用defaultConfig获取默认配置

cmd\containerd\command\config.go
func defaultConfig() *srvconfig.Config {
    return platformAgnosticDefaultConfig()
}

func platformAgnosticDefaultConfig() *srvconfig.Config {
    return &srvconfig.Config{
        Version: version.ConfigVersion,
        Root:    defaults.DefaultRootDir,
        State:   defaults.DefaultStateDir,
        GRPC: srvconfig.GRPCConfig{
            Address:        defaults.DefaultAddress,
            MaxRecvMsgSize: defaults.DefaultMaxRecvMsgSize,
            MaxSendMsgSize: defaults.DefaultMaxSendMsgSize,
        },
        DisabledPlugins:  []string{},
        RequiredPlugins:  []string{},
        StreamProcessors: streamProcessors(),
    }
}
defaults.DefaultAddress 在defaults包下有多个系统(linux、windows、freebsd等)的定义,那编译的时候是怎么识别使用哪个系统的配置?答案是根据系统类型或指定的GOOS,来选择对应系统结尾的文件的进行编译的。例如:如果是linux,则选择以linux结尾的defaults_linux.go文件进行编译;如果是windows,则选择以windows结尾的default_windows.go文件进行编译。
 

unix domain socket地址

defaults\defaults_linux.go
1 const (
2     // DefaultAddress is the default unix socket address
3     DefaultAddress = "/run/containerd/containerd.sock"
4 )

 

posted @ 2025-10-20 11:42  xiaoxiongfei  阅读(6)  评论(0)    收藏  举报