成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

docker進(jìn)程模型,架構(gòu)分析

mingzhong / 3530人閱讀

摘要:與容器內(nèi)第一個(gè)進(jìn)程進(jìn)程看創(chuàng)建了這么多子進(jìn)程,然后到了我們期待的自己中的進(jìn)程就要被創(chuàng)建了,想想都有點(diǎn)小激動(dòng),然而。。。

Docker架構(gòu)分析
[root@docker-build-86-050 ~]# ls /usr/bin |grep docker
docker
docker-compose
docker-containerd
docker-containerd-ctr
docker-containerd-shim
dockerd
docker-proxy
docker-runc

大家一定很困惑 dockerd, containerd, ctr,shim, runc,等這幾個(gè)進(jìn)程的關(guān)系到底是啥

初窺得出的結(jié)論是:

docker是cli沒(méi)啥可說(shuō)的

dockerd是docker engine守護(hù)進(jìn)程,dockerd啟動(dòng)時(shí)會(huì)啟動(dòng)containerd子進(jìn)程。

dockerd與containerd通過(guò)rpc進(jìn)行通信

ctr是containerd的cli

containerd通過(guò)shim操作runc,runc真正控制容器生命周期

啟動(dòng)一個(gè)容器就會(huì)啟動(dòng)一個(gè)shim進(jìn)程

shim直接調(diào)用runc的包函數(shù),shim與containerd之前通過(guò)rpc通信

真正用戶想啟動(dòng)的進(jìn)程由runc的init進(jìn)程啟動(dòng),即runc init [args ...]

進(jìn)程關(guān)系模型:

docker     ctr
  |         |
  V         V
dockerd -> containerd ---> shim -> runc -> runc init -> process
                      |-- > shim -> runc -> runc init -> process
                      +-- > shim -> runc -> runc init -> process
[root@docker-build-86-050 ~]# ps -aux|grep docker
root      3925  0.0  0.1 2936996 74020 ?       Ssl  3月06  68:14 /usr/bin/dockerd --storage-driver=aufs -H 0.0.0.0:2375 --label ip=10.1.86.50 -H unix:///var/run/docker.sock --insecure-registry 192.168.86.106 --insecure-registry 10.1.86.51 --insecure-registry dev.reg.iflytek.com
root      3939  0.0  0.0 1881796 27096 ?       Ssl  3月06   9:10 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --shim docker-containerd-shim --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --runtime docker-runc
root     21238  0.0  0.0 487664  6212 ?        Sl   4月20   0:00 docker-containerd-shim 48119c50a0ca8a53967364f75fb709017cc272ae248b78062e0dafaa22108d21 /var/run/docker/libcontainerd/48119c50a0ca8a53967364f75fb709017cc272ae248b78062e0dafaa22108d21 docker-runc
dockerd 與 containerd 之間的基情

首先dockerd的main函數(shù)相信你能找到cmd/dockerd/docker.go

其它的先略過(guò),直接進(jìn)start看一看:

err = daemonCli.start(opts)

這函數(shù)里我們先去關(guān)注兩件事:

創(chuàng)建了多個(gè)Hosts,這是給client去連接的,dockerd啟動(dòng)時(shí)用-H參數(shù)指定,可以是多個(gè),如指定一個(gè)tcp 指定一個(gè)unix sock( -H unix:///var/run/docker.sock)

創(chuàng)建了containerd子進(jìn)程

這個(gè)New很重要

containerdRemote, err := libcontainerd.New(cli.getLibcontainerdRoot(), cli.getPlatformRemoteOptions()...)

進(jìn)去看看:

...
    err := r.runContainerdDaemon(); 
...
    conn, err := grpc.Dial(r.rpcAddr, dialOpts...)
    if err != nil {
        return nil, fmt.Errorf("error connecting to containerd: %v", err)
    }

    r.rpcConn = conn
    r.apiClient = containerd.NewAPIClient(conn)
...

啟動(dòng)了一個(gè)containerd進(jìn)程,并與之建立連接。通過(guò)protobuf進(jìn)行rpc通信, grpc相關(guān)介紹看這里

具體如何創(chuàng)建containerd進(jìn)程的可以進(jìn)入runContainerDaemon里細(xì)看

    cmd := exec.Command(containerdBinary, args...)
    // redirect containerd logs to docker logs
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.SysProcAttr = setSysProcAttr(true)
    cmd.Env = nil
    // clear the NOTIFY_SOCKET from the env when starting containerd
    for _, e := range os.Environ() {
        if !strings.HasPrefix(e, "NOTIFY_SOCKET") {
            cmd.Env = append(cmd.Env, e)
        }
    }
    if err := cmd.Start(); err != nil {
        return err
    }

看不明白的話,去標(biāo)準(zhǔn)庫(kù)里惡補(bǔ)一下cmd怎么用。 cmd.Start()異步創(chuàng)建進(jìn)程,創(chuàng)建完直接返回

所以創(chuàng)建一個(gè)協(xié)程等待子進(jìn)程退出

    go func() {
        cmd.Wait()
        close(r.daemonWaitCh)
    }() // Reap our child when needed
docker-containerd-shim是何方神圣 與containerd和runc又有什么關(guān)系?

代碼中的一句話解釋?zhuān)?b>shim for container lifecycle and reconnection, 容器生命周期和重連, 所以可以順著這個(gè)思路去看。

先看containerd/linux/runtime.go里的一段代碼:
Runtime 的Create方法里有這一行,這里的Runtime對(duì)象也是注冊(cè)到register里面的,可以看init函數(shù),然后containerd進(jìn)程啟動(dòng)時(shí)去加載了這個(gè)Runtime

s, err := newShim(path, r.remote)

縮減版內(nèi)容:

func newShim(path string, remote bool) (shim.ShimClient, error) {
    l, err := sys.CreateUnixSocket(socket) //創(chuàng)建了一個(gè)UnixSocket
    cmd := exec.Command("containerd-shim")
    f, err := l.(*net.UnixListener).File()
    cmd.ExtraFiles = append(cmd.ExtraFiles, f) //留意一下這個(gè),非常非常重要,不知道這個(gè)原理可能就看不懂shim里面的代碼了
    if err := reaper.Default.Start(cmd); err != nil { //啟動(dòng)了一個(gè)shim進(jìn)程
    }
    return connectShim(socket) // 這里返回了與shim進(jìn)程通信的客戶端
}

再去看看shim的代碼:
shim進(jìn)程啟動(dòng)干的最主要的一件事就是啟動(dòng)一個(gè)grpc server:

if err := serve(server, "shim.sock"); err != nil {

進(jìn)去一探究竟:

func serve(server *grpc.Server, path string) error {
    l, err := net.FileListener(os.NewFile(3, "socket"))
    logrus.WithField("socket", path).Debug("serving api on unix socket")
    go func() {
        if err := server.Serve(l); err != nil &&
        }
    }()
}

我曾經(jīng)因?yàn)檫@個(gè)os.NewFile(3, "socket")看了半天看不懂,為啥是3?聯(lián)系cmd.ExtraFiles = append(cmd.ExtraFiles, f) 創(chuàng)建shim進(jìn)程時(shí)的這句,問(wèn)題解決了。

這個(gè)3的文件描述符,就是containerd用于創(chuàng)建UnixSocket的文件,這樣containerd的client剛好與這邊啟動(dòng)的 grpc server連接上了,可以遠(yuǎn)程調(diào)用其接口了:

type ContainerServiceClient interface {
    Create(ctx context.Context, in *CreateRequest, opts ...grpc.CallOption) (*CreateResponse, error)
    Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
    Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error)
    Info(ctx context.Context, in *InfoRequest, opts ...grpc.CallOption) (*containerd_v1_types1.Container, error)
    List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error)
    Kill(ctx context.Context, in *KillRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
    Events(ctx context.Context, in *EventsRequest, opts ...grpc.CallOption) (ContainerService_EventsClient, error)
    Exec(ctx context.Context, in *ExecRequest, opts ...grpc.CallOption) (*ExecResponse, error)
    Pty(ctx context.Context, in *PtyRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
    CloseStdin(ctx context.Context, in *CloseStdinRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
}

containerd與shim通信模型介紹

再看shim與runc的關(guān)系,這個(gè)比較簡(jiǎn)單了,直接進(jìn)入shim service 實(shí)現(xiàn)的Create方法即可

sv = shim.New(path)
func (s *Service) Create(ctx context.Context, r *shimapi.CreateRequest) (*shimapi.CreateResponse, error) {
    process, err := newInitProcess(ctx, s.path, r)
    return &shimapi.CreateResponse{
        Pid: uint32(pid),
    }, nil
}

進(jìn)入到newInitProcess里面:

func newInitProcess(context context.Context, path string, r *shimapi.CreateRequest) (*initProcess, error) {
    runtime := &runc.Runc{
        Command:      r.Runtime,
        Log:          filepath.Join(path, "log.json"),
        LogFormat:    runc.JSON,
        PdeathSignal: syscall.SIGKILL,
    }
    p := &initProcess{
        id:     r.ID,
        bundle: r.Bundle,
        runc:   runtime,
    }
  
    if err := p.runc.Create(context, r.ID, r.Bundle, opts); err != nil {
        return nil, err
    }
    return p, nil
}

可以看到,在這里調(diào)用了runc的API去真正執(zhí)行創(chuàng)建容器的操作。其本質(zhì)是調(diào)用了runc create --bundle [bundle] [containerid] 命令,在此不多作介紹了

shim進(jìn)程與runc進(jìn)程之間

上文可知,shim進(jìn)程創(chuàng)建runc子進(jìn)程。

runc 與 容器內(nèi)第一個(gè)進(jìn)程 init進(jìn)程

看docker創(chuàng)建了這么多子進(jìn)程,然后到了runc我們期待的自己Dockerfile中的CMD進(jìn)程就要被創(chuàng)建了,想想都有點(diǎn)小激動(dòng),然而。。。

runc進(jìn)程啟動(dòng)后會(huì)去啟動(dòng)init進(jìn)程,去創(chuàng)建容器,然后在容器中創(chuàng)建進(jìn)程,那才是真正我們需要的進(jìn)程

關(guān)于runc init進(jìn)程關(guān)鍵看StartInitialization方法(main_unix.go)

docker-containerd-ctr 與 docker-containerd

ctr 是一個(gè)containerd的client,之間通過(guò)proto rpc通信, containerd監(jiān)聽(tīng)了unix:///run/containerd/containerd.sock。

[root@dev-86-201 ~]# docker-containerd --help
NAME:
   containerd - High performance container daemon

USAGE:
   docker-containerd [global options] command [command options] [arguments...]

VERSION:
   0.2.0 commit: 0ac3cd1be170d180b2baed755e8f0da547ceb267

COMMANDS:
   help, h    Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug                            enable debug output in the logs
   --state-dir "/run/containerd"                runtime state directory
   --metrics-interval "5m0s"                    interval for flushing metrics to the store
   --listen, -l "unix:///run/containerd/containerd.sock"    proto://address on which the GRPC API will listen
   --runtime, -r "runc"                        name or path of the OCI compliant runtime to use when executing containers
   --runtime-args [--runtime-args option --runtime-args option]    specify additional runtime args
   --shim "containerd-shim"                    Name or path of shim
   --pprof-address                         http address to listen for pprof events
   --start-timeout "15s"                    timeout duration for waiting on a container to start before it is killed
   --retain-count "500"                        number of past events to keep in the event log
   --graphite-address                         Address of graphite server
   --help, -h                            show help
   --version, -v                        print the version
[root@dev-86-201 ~]# docker-containerd-ctr --help
NAME:
   ctr - High performance container daemon cli

USAGE:
   docker-containerd-ctr [global options] command [command options] [arguments...]

VERSION:
   0.2.0 commit: 0ac3cd1be170d180b2baed755e8f0da547ceb267

COMMANDS:
   checkpoints    list all checkpoints
   containers    interact with running containers
   events    receive events from the containerd daemon
   state    get a raw dump of the containerd state
   version    return the daemon version
   help, h    Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug                        enable debug output in the logs
   --address "unix:///run/containerd/containerd.sock"    proto://address of GRPC API
   --conn-timeout "1s"                    GRPC connection timeout
   --help, -h                        show help
   --version, -v                    print the version
runc 架構(gòu)破析

比較復(fù)雜也比較重要,所以我將多帶帶寫(xiě)一篇相關(guān)的介紹 這里

使用runc直接創(chuàng)建容器
mkdir /mycontainer
cd /mycontainer
mkdir rootfs
docker export $(docker create busybox) | tar -C rootfs -xvf -
# 生成容器的配置文件config.json
runc spec
runc run mycontainerid
容器狀態(tài)文件

默認(rèn)存在/run/runc目錄下,不管是docker engine創(chuàng)建的容器還是通過(guò)runc直接創(chuàng)建的容器都會(huì)在/run/runc目錄下創(chuàng)建一個(gè)以容器名命名的目錄,下面有個(gè)state.json文件用于存儲(chǔ)文件狀態(tài)

更多問(wèn)題歡迎關(guān)注我的github: https://github.com/fanux

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/27049.html

相關(guān)文章

  • TensorFlow在產(chǎn)品環(huán)境中運(yùn)行模型的實(shí)踐經(jīng)驗(yàn)總結(jié)

    摘要:它使用機(jī)器學(xué)習(xí)來(lái)解釋用戶提出的問(wèn)題,并用相應(yīng)的知識(shí)庫(kù)文章來(lái)回應(yīng)。使用一類(lèi)目前較先進(jìn)的機(jī)器學(xué)習(xí)算法來(lái)識(shí)別相關(guān)文章,也就是深度學(xué)習(xí)。接下來(lái)介紹一下我們?cè)谏a(chǎn)環(huán)境中配置模型的一些經(jīng)驗(yàn)。 我們?nèi)绾伍_(kāi)始使用TensorFlow ?在Zendesk,我們開(kāi)發(fā)了一系列機(jī)器學(xué)習(xí)產(chǎn)品,比如的自動(dòng)答案(Automatic Answers)。它使用機(jī)器學(xué)習(xí)來(lái)解釋用戶提出的問(wèn)題,并用相應(yīng)的知識(shí)庫(kù)文章來(lái)回應(yīng)。當(dāng)用戶有...

    stackfing 評(píng)論0 收藏0
  • docker 的特點(diǎn)、組件、功能。

    摘要:鏡像鏡像是構(gòu)建的基石。公司運(yùn)營(yíng)公共的叫做。標(biāo)準(zhǔn)集裝箱將貨物運(yùn)往世界各地,將這個(gè)模型運(yùn)用到自己的設(shè)計(jì)中,唯一不同的是集裝箱運(yùn)輸貨物,而運(yùn)輸軟件。這一點(diǎn)在面向服務(wù)的架構(gòu)和重度依賴微型服務(wù)的部署由其實(shí)用。用創(chuàng)建隔離的環(huán)境來(lái)進(jìn)行測(cè)試。 Docker特點(diǎn)1)上手快 用戶只需要幾分鐘,就可以把自己的程序Docker 化。Docker 依賴于寫(xiě)時(shí)復(fù)制 (copy-on-write)模型,使修改應(yīng)用程...

    saucxs 評(píng)論0 收藏0
  • docker進(jìn)階,nginx部署的幾個(gè)重要點(diǎn)詳解以及開(kāi)發(fā)流程---持續(xù)更新

    摘要:無(wú)論這個(gè)連接是外部主動(dòng)建立的,還是內(nèi)部建立的。協(xié)議有表示層數(shù)據(jù)的表示安全壓縮。在整個(gè)發(fā)展過(guò)程中的所有思想和著重點(diǎn)都以一種稱為的文檔格式存在。 部署基礎(chǔ)知識(shí)url:協(xié)議://網(wǎng)站地址:端口(/)路徑地址?參數(shù)eg: http://www.baidu.com:80/abc/dd/ www.baidu.com找服務(wù)器 80端口:找服務(wù)器上提供服務(wù)的應(yīng)用 nginx uri:/ab...

    KunMinX 評(píng)論0 收藏0
  • docker進(jìn)階,nginx部署的幾個(gè)重要點(diǎn)詳解以及開(kāi)發(fā)流程---持續(xù)更新

    摘要:無(wú)論這個(gè)連接是外部主動(dòng)建立的,還是內(nèi)部建立的。協(xié)議有表示層數(shù)據(jù)的表示安全壓縮。在整個(gè)發(fā)展過(guò)程中的所有思想和著重點(diǎn)都以一種稱為的文檔格式存在。 部署基礎(chǔ)知識(shí)url:協(xié)議://網(wǎng)站地址:端口(/)路徑地址?參數(shù)eg: http://www.baidu.com:80/abc/dd/ www.baidu.com找服務(wù)器 80端口:找服務(wù)器上提供服務(wù)的應(yīng)用 nginx uri:/ab...

    ytwman 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<