This is a creation in Article, where the information may have evolved or changed.
Docker daemon
docker client swarm
the handler function that initializes the response-related command is located at api/server/router/swarm/cluster.go
:
Buildrouter is a router to talk with the build Controllertype swarmrouter struct {backend backend routes []rout Er. route}//Newrouter Initializes a new build Routerfunc Newrouter (b backend) router. Router {r: = &swarmrouter{Backend:b,} r.initroutes () return r}//Routes returns the available R Outers to the Swarm Controllerfunc (SR *swarmrouter) Routes () []router. Route {return Sr.routes}func (SR *swarmrouter) Initroutes () {sr.routes = []router]. route{router. Newpostroute ("/swarm/init", sr.initcluster), router. Newpostroute ("/swarm/join", sr.joincluster), router. Newpostroute ("/swarm/leave", sr.leavecluster), router. Newgetroute ("/swarm", sr.inspectcluster), router. Newpostroute ("/swarm/update", sr.updatecluster), router. Newgetroute ("/services", sr.getservices), router. Newgetroute ("/services/{id:.*}", Sr.getservice), router. Newpostroute ("/services/create", Sr.createservice), router. NewposTroute ("/services/{id:.*}/update", Sr.updateservice), router. Newdeleteroute ("/services/{id:.*}", Sr.removeservice), router. Newgetroute ("/nodes", sr.getnodes), router. Newgetroute ("/nodes/{id:.*}", Sr.getnode), router. Newdeleteroute ("/nodes/{id:.*}", Sr.removenode), router. Newpostroute ("/nodes/{id:.*}/update", Sr.updatenode), router. Newgetroute ("/tasks", sr.gettasks), router. Newgetroute ("/tasks/{id:.*}", Sr.gettask),}}
To process the "/swarm/init
" request as an example, the actual processing function is located in daemon/cluster/cluster.go
:
Init initializes new cluster from user provided Request.func (c *cluster) Init (req types. Initrequest) (string, error) {C.lock () if node: = c.node; Node! = nil {if!req. Forcenewcluster {c.unlock () return "", errswarmexists} If Err: = C.stopnode (); Err! = Nil {c.unlock () return "", err}} If err: = Validateandsanitizeinitrequest (&am P;REQ); Err! = Nil {c.unlock () return "", err} listenhost, Listenport, err: = Resolvelistenaddr (req. LISTENADDR) If err! = Nil {c.unlock () return "", err} advertisehost, Advertiseport, err: = C.reso LVEADVERTISEADDR (req. ADVERTISEADDR, Listenport) if err! = Nil {c.unlock () return "", err} localaddr: = Listenhost/ /If The advertise address is not one of the system ' s//addresses, we also require a listen address. Listenaddrip: = Net. PARSEIP (listenhost) if listenaddrip! = Nil && lisTenaddrip.isunspecified () {advertiseip: = net. PARSEIP (advertisehost) if Advertiseip = = Nil {//Not an IP C.unlock () return "", ERRMUSTSPECIFYLISTENADDR} systemips: = Listsystemips () Found: = False for _, Systemip: = Rang E systemips {if systemip.equal (ADVERTISEIP) {found = True break} If!found {c.unlock () return "", errmustspecifylistenaddr} localaddr = Advertiseip.string ()}//Todo:check current state existing n, err: = C.startnewnode (req. Forcenewcluster, Localaddr, "", net. Joinhostport (Listenhost, Listenport), net. Joinhostport (Advertisehost, Advertiseport), "", "" ") if err! = Nil {c.unlock () return" ", err} c.u Nlock () Select {Case <-n.ready (): If err: = Initclusterspec (n, req. SPEC); Err! = Nil {return "", err} go C.reconneCtonfailure (n) return N.nodeid (), Nil case <-n.done:c.rlock () defer c.runlock () if!req . Forcenewcluster {//If failure on first attempt don't keep state if err: = C.clearstate (); Err! = Nil { Return "", Err}} return "", C.err}}
Its core is the c.startNewNode
function, and its main logic is as follows:
......n, err := swarmagent.NewNode(&swarmagent.NodeConfig{ Hostname: c.config.Name, ForceNewCluster: forceNewCluster, ListenControlAPI: filepath.Join(c.root, controlSocket), ListenRemoteAPI: listenAddr, AdvertiseRemoteAPI: advertiseAddr, JoinAddr: joinAddr, StateDir: c.root, JoinToken: joinToken, Executor: container.NewExecutor(c.config.Backend), HeartbeatTick: 1, ElectionTick: 3,})if err != nil { return nil, err}ctx := context.Background()if err := n.Start(ctx); err != nil { return nil, err}......
That is swarmkit
, the call NewNode
creates one node
, and then start
the node. This node
is a manager
character.