docker

1, 什么是容器

容器是一个在单一主机上提供多个隔离的 Linux 环境的虚拟化技术。

不像虚拟机(VM),容器并不需要运行专有的访客操作系统。 多个容器共享宿主机的 host 操作系统内核, 并使用访客操作系统的系统库来提供所需的功能。

2, 什么是docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中, 然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。docker容器是完全使用沙箱机制,相互之间不会有任何接口。

Docker有着比虚拟机更少的抽象层,利用的是宿主机的内核,因此性能比虚拟机高。

3, 安装docker

在 ubuntu 22.04 下 docker 安装命令

sudo apt install docker.io

安装后查看版本

$ docker version
Client:
 Version:           20.10.12
 API version:       1.41
 Go version:        go1.17.3
 Git commit:        20.10.12-0ubuntu4
 Built:             Mon Mar  7 17:10:06 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server:
 Engine:
  Version:          20.10.12
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.17.3
  Git commit:       20.10.12-0ubuntu4
  Built:            Mon Mar  7 15:57:50 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.5.9-0ubuntu3
  GitCommit:
 runc:
  Version:          1.1.0-0ubuntu1.1
  GitCommit:
 docker-init:
  Version:          0.19.0
  GitCommit:

在centOS上

wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum install -y docker

docker基本概念

  • 镜像(Image),是打包的应用程序和操作系统,提供容器运行时所需的库、程序和配置等等。

  • 容器(Container),镜像运行就是实际的容器。

  • 仓库(Repository),镜像集中存储的地方。

  • 标签(label), 镜像的版本号。

国内加速

docker的服务器在国外,下载镜像的访问速度很慢,为了进行加速,可以设置一些国内代理,修改 /etc/docker/daemon.json 文件, 添加上 registry-mirrors 键值。

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}

修改保存后重启 Docker 以使配置生效。重启命令

systemctl restart docker

常用命令

docker pull python:3 获取镜像

docker image ls 查看本地image镜像,是下载下来的镜像。

docker run -it –rm python:3 python 运行镜像(镜像名为python:3)中的python交互解释器。 可以看到Python 3.11.0 类似的关键字。通过exit()退出Python解释器,同时也退出了容器。

docker run -p 8000:8000 -it –rm python:3 python -m http.server

设置端口映射,8000端口映射到docker容器的8000端口,容器里面启动python的http.server

启动成功后,会创建docker0的一个网卡,并设置IP地址,然后在内核写入一条docker0网口的路由。 可以通过 ip route 命令来查看。在启动之前,网卡是down状态,启动之后网卡是up状态。

可以通过–name来对容器进行命名,例如

docker run --name bjbook -p 8000:8000 -it --rm python:3  python -m  http.server

容器命名为bjbook, 我们可以进入容器,然后修改容器的内容

docker exec -it bjbook bash

修改完成后保存容器为镜像, 命令为

docker commit bjbook  python:v2

保存完成后,可以使用docker image ls命令来查看。

常用选项 :

  • run 创建并运行一个容器

  • -it 可交互终端

  • rm 删除容器

  • -d 放入后台

  • -p 端口映射

镜像删除

docker image rm

docker inspect

docker inspect命令查看镜像详细信息,包括创建者,环境变量,启动命令以及各层的摘要等。 可以看到buildbot-worker启动命令为 /usr/bin/dumb-init twistd –pidfile= -ny buildbot.tac

[root@node1 ]# docker inspect docker.io/buildbot/buildbot-worker
[
        {
                "Id": "sha256:257afc9fe8c3bddb14594c1d6028e5e364c89993c15e374bcf9d215ed66b6d7a",
                "RepoTags": [
                        "docker.io/buildbot/buildbot-worker:latest"
                ],
                "RepoDigests": [
                        "docker.io/buildbot/buildbot-worker@sha256:5750c41e87aad00bf2a88b54e71a569444c81fcca4a8eef7ea4b9778b7fc392c"
                ],
                "Parent": "",
                "Comment": "",
                "Created": "2020-08-22T18:12:44.410376373Z",
                "Container": "d59d8a0473f97ee154345a61c208ea0e1b87819eb4d541e6dfc63bafd538c872",
                "ContainerConfig": {
                        "Hostname": "d59d8a0473f9",
                        "Domainname": "",
                        "User": "buildbot",
                        "AttachStdin": false,
                        "AttachStdout": false,
                        "AttachStderr": false,
                        "Tty": false,
                        "OpenStdin": false,
                        "StdinOnce": false,
                        "Env": [
                                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                                "security_updates_as_of=2018-06-15"
                        ],
                        "Cmd": [
                                "/bin/sh",
                                "-c",
                                "#(nop) ",
                                "CMD [\"/usr/bin/dumb-init\" \"twistd\" \"--pidfile=\" \"-ny\" \"buildbot.tac\"]"
                        ],
                        "Image": "sha256:4a29f57c9ac0728f82cb8700e483f9a0e90400c357d2f2f79fde1645c707190d",
                        "Volumes": null,
                        "WorkingDir": "/buildbot",
                        "Entrypoint": null,
                        "OnBuild": null,
                        "Labels": {}
                },
                "DockerVersion": "19.03.8",
                "Author": "Buildbot maintainers",
                "Config": {
                        "Hostname": "",
                        "Domainname": "",
                        "User": "buildbot",
                        "AttachStdin": false,
                        "AttachStdout": false,
                        "AttachStderr": false,
                        "Tty": false,
                        "OpenStdin": false,
                        "StdinOnce": false,
                        "Env": [
                                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                                "security_updates_as_of=2018-06-15"
                        ],
                        "Cmd": [
                                "/usr/bin/dumb-init",
                                "twistd",
                                "--pidfile=",
                                "-ny",
                                "buildbot.tac"
                        ],
                        "Image": "sha256:4a29f57c9ac0728f82cb8700e483f9a0e90400c357d2f2f79fde1645c707190d",
                        "Volumes": null,
                        "WorkingDir": "/buildbot",
                        "Entrypoint": null,
                        "OnBuild": null,
                        "Labels": null
                },
                "Architecture": "amd64",
                "Os": "linux",
                "Size": 528922550,
                "VirtualSize": 528922550,
                "GraphDriver": {
                        "Name": "overlay2",
                        "Data": {
                                "LowerDir": "/var/lib/docker/overlay2/5d113a1bde8c09152d14c8f2f75b60e4c26f2023c7dce719c051475644e30346/diff:/var/lib/docker/overlay2/1911afbdff822d15dfbb6a077280c811ee49067db032d3fbe21ec3654668ce14/diff:/var/lib/docker/overlay2/b651a916655df45d5ff516ee78fe1d526ea951ca60d8f4a2018bfae6c2063db3/diff:/var/lib/docker/overlay2/353cd38ae4ccd945a466611482a0cfce7108f29713b88f8ff44a691d583f4b15/diff:/var/lib/docker/overlay2/c90ece8c40a706946823f78fb322c3704a6eb688f8ac4ae6f210cdca667d8d07/diff:/var/lib/docker/overlay2/6bd9e4abb9a5e679d50fc50c5d6cde84cfde392f0e9e4e75fdfbc06150801d55/diff:/var/lib/docker/overlay2/9ff3a4b96a37ab53f4838820162345530119e7b3573aa530bd6c69e717799186/diff",
                                "MergedDir": "/var/lib/docker/overlay2/c1bf18f217e7a1bdd3dc4b8224e9224e0de77cd330f6bd8b2a74d21e8ce935f9/merged",
                                "UpperDir": "/var/lib/docker/overlay2/c1bf18f217e7a1bdd3dc4b8224e9224e0de77cd330f6bd8b2a74d21e8ce935f9/diff",
                                "WorkDir": "/var/lib/docker/overlay2/c1bf18f217e7a1bdd3dc4b8224e9224e0de77cd330f6bd8b2a74d21e8ce935f9/work"
                        }
                },
                "RootFS": {
                        "Type": "layers",
                        "Layers": [
                                "sha256:79bde4d54386664324ce9b6179a3265ca96e6c8f05c06ded53856a670874c715",
                                "sha256:2f37d11021878811b25cc6a3c6d48a0eb6f57a0b0d42f954123a18c17e2abf56",
                                "sha256:2ba5b91ca2b0c27b8ca3503b93164e9ec29ef5ae72e5272192839347e9f951dd",
                                "sha256:001e4a80973b4bc154292425871684a0c1fa422c344186516dd6f792606ed9d6",
                                "sha256:6f31daeebfa5c0339bb43379dfd7560a94a93537f4785ebcbe05af915b2a33a6",
                                "sha256:846a90b0083f3d93dd330ebe661771099a5d5bfe631a8ddc0e9ecea9ba351efa",
                                "sha256:1a4d0278e9d6bc438124468a24c35b4dc5544ed63e407e668ae2c24e15e92a7f",
                                "sha256:1382aeec657d0f4e17143373f5f4f0b44a76619b0520063c15994942e68f8a93"
                        ]
                }
        }
]

基于已有镜像创建自定义镜像

下载已有镜像, 然后运行镜像, 安装软件, 最后修改镜像的启动脚本。

1, 下载镜像, 我们基于centos创建新镜像, 因此先下载centos

docker pull docker.io/centos

2, 基于centos镜像创建容器并运行, 命名容器为buildbot

docker run --name buildbot -dit  -p 80:80 centos

3, 进入容器, 然后安装软件

docker attach buildbot

然后安装软件, 我这里安装buildbot客户端,以及一些编译工具

yum install -y python3 make git-core which
pip3 install buildbot-worker
pip3 install dumb-init

4, 构建镜像

退出容器,然后基于当前的容器构建镜像

docker commit -m "+buildbot+python3" -a "zhangyz" -c 'CMD ["/usr/local/bin/dumb-init", "twistd", "--pidfile=", "-ny", "/root/buildbot.tac"] WORKDIR "/root"' buildbot centos_buildbot:2.0
  • -m 来指定提交的说明信息。

  • -a 可以指定更新的用户信息。

  • -c 修改新镜像执行的命令

  • buildbot 创建镜像的容器名称或ID,就是基于哪个容器重新制作镜像。

  • 最后指定目标镜像的名称和 标签信息。创建成功后会返回这个镜像的 ID 信息。centos_buildbot 构建之后的镜像名称

实际的启动命令为: dumb-init twistd –pidfile= -ny buildbot.tac

构建镜像简易命令

docker commit buildbot centos_buildbot:2.0

buildbot为容器名称,centos_buildbot:2.0 为镜像名称及版本。

推送到本地运行的 Registry仓库

1, 创建标签

docker image tag centos_buildbot:2.0 localhost:5000/centos_buildbot

2, 推送 centos_buildbot

docker push localhost:5000/centos_buildbot

3,拉取

docker pull localhost:5000/centos_buildbot

4, 运行容器验证是否成功

docker run –name my_buildbot -dit -p 80:80 localhost:5000/centos_buildbot

导入或导出

1, 导出镜像

docker save -o ~/centos_buildbot.tar.gz centos_buildbot:2.0

2, 导入镜像

docker load -i ~/centos_buildbot.tar.gz

docker拷贝文件

docker cp <containerId>:/containerpath/src /hostpath/target

容器和镜像常用命令

docker image ls 显示image列表

docker rmi openwrt:18.06.4.1 删除指定image。

docker rmi bc8078abe3ad 根据ID来删除指定image。

docker container ls -a 显示所有的容器

docker container prune 移除所有停止的容器

docker container cp 在容器和本地文件系统之间复制文件

docker ps 列出运行中的容器。

docker镜像加速

使用配置文件 /etc/docker/daemon.json 修改为以下配置

{
        "registry-mirrors": ["https://registry.docker-cn.com"]
}

然后重启Docker,命令为: systemctl restart docker

docker 停止所有容器

docker stop $(docker ps -a -q)

删除所有容器

docker  rm $(docker ps -a -q)

问题解答

1,docker里面执行iptables,提示权限不足,但已经使用了root用户。

解决方法:启动时缺少 –privileged 导致,启动docker容器时,加上–privileged参数

2, docker pull时提示以下错误

x509: cannot validate certificate for xx.xx.xx.xx because it doesn't contain any IP SANs

解决方法:在/etc/docker/daemon.json, 增加一行

"insecure-registries" : ["10.137.22.181"],

不安全的注册服务器地址,不用验证其安全性。

参考资料

http://yeasy.gitbook.io/docker_practice/

https://openwrt.org/docs/guide-user/virtualization/docker_openwrt_image

更新日期 2022.11