开发利器(二):Docker使用备忘

Docker

目录

基础和原则

  1. 按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者 绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
  2. 容器基于镜像。类似于运行的进程 基于 编译代码得到的bin文件一样
  3. 镜像是多层存储,每一层是在前一层的基础上进行的修改;而容器同样也是多层存储,是在以镜像为基础层,在其基础上加一层作为容器运行时的存储层。镜像所使用的分层存储的概念,除当前层外,之前的每一层都是不会发生改变的,换句话说,任何修改的结果仅仅是在当前层进行标记、添加、修改,而不会改动上一层。如果使用 docker commit 制作镜像,以及后期修改的话,每一次修改都会让镜像更加臃肿一次,所删除的上一层的东西并不会丢失,会一直如影随形的跟着这个镜像,即使根本无法访问到。这会让镜像更加臃肿。

常见操作

如何下载镜像?
  • docker pull ubuntu:20.04
如何推送镜像到远程库 ?
# 需要提前登录 通过执行 docker login 命令交互式的输入用户名及密码来完成在命令行界面登录 Docker Hub
$ docker tag ubuntu:18.04 username/ubuntu:18.04   #username 请替换为Docker 账号用户名 junfiredocker
$ docker image ls
REPOSITORY                                               TAG                    IMAGE ID            CREATED             SIZE
ubuntu                                                   18.04                  275d79972a86        6 days ago          94.6MB
username/ubuntu                                          18.04                  275d79972a86        6 days ago          94.6MB

$ docker push username/ubuntu:18.04
$ docker search username
NAME                      DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
username/ubuntu
如何彻底删除镜像?
如何导入和导出镜像 ?
  • docker save docker load ,如果是镜像迁移应该直接使用 Docker Registry, Registry即注册服务器, 是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 docker.io/ubuntu 来说,docker.io 是注册服务器地址,ubuntu 是仓库名。
怎么启动一个容器 ?
  • docker run -t -i ubuntu:20.04 /bin/bash # 启动一个 bash 终端,允许用户进行交互, 如果加-d 参数,表示在后台执行
如何进入容器(容器已经启动) ?
  • 在使用 -d 参数时,容器启动后会进入后台。 推荐大家使用 docker exec 命令进入容器
$ docker run -dit ubuntu    #启动容器

69d137adef7a8a689cbcb059e94da5489d3cddd240ff675c640c8d96e84fe1f6

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
69d137adef7a        ubuntu:latest       "/bin/bash"         18 seconds ago      Up 17 seconds                           zealous_swirles

$ docker exec -it 69d1 bash
root@69d137adef7a:/#
怎么终止一个容器 ?

docker container stop

怎么删除处于终止状态的容器 ?
$ docker container rm trusting_newton
trusting_newton

# 如果要删除一个运行中的容器,可以添加 -f 参数, Docker 会发送 SIGKILL 信号给容器。

# 清理所有处于终止状态的容器
$ docker container prune
怎么启动一个已经终止的容器 ?

docker container start # 终止状态的容器可以用 docker container ls -a 命令看到

怎么重启一个容器?

docker container restart

怎么把容器里的修改保存成一个新的镜像?
  1. 直接使用docker export , 然后再docker import ? 这样就没有历史记录信息,更好
  2. docker commit (慎用)
  3. 用Dockerfile构建
如何导入和导出容器 ?
# 导出使用 docker export 命令
$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                    PORTS               NAMES
7691a814370e        ubuntu:18.04        "/bin/bash"         36 hours ago        Exited (0) 21 hours ago                       test
$ docker export 7691a814370e > ubuntu.tar     # 这样将导出容器快照到本地文件
# 导入使用 docker import 从容器快照文件中再导入为镜像
$ cat ubuntu.tar | docker import - test/ubuntu:v1.0
$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
test/ubuntu         v1.0                9d37a6082e97        About a minute ago   171.3 MB

# 此外,也可以通过指定 URL 或者某个目录来导入,例如
$ docker import http://example.com/exampleimage.tgz example/imagerepo
  • 用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以使用 docker import来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。
挂载主机目录(或者创建数据卷后再挂载)
# 加载主机的 /src/webapp 目录到容器的 /usr/share/nginx/html目录
$ docker run -d -P \
    --name web \
    -v /src/webapp:/usr/share/nginx/html  # 等同于这个命令 --mount type=bind,source=/src/webapp,target=/usr/share/nginx/html \
    nginx:alpine



# 也可以创建一个数据卷,然后挂载到容器里。所谓数据卷本质上就是在主机专用的docker目录下创建一个新的目录
$ docker volume create my-vol
# 查看指定 数据卷 的信息
$ docker volume inspect my-vol
[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": {},
        "Scope": "local"
    }
]
# 载一个 数据卷 my-vol到容器的 /usr/share/nginx/html 目录
$ docker run -d -P \
    --name web \
    # -v my-vol:/usr/share/nginx/html \
    --mount source=my-vol,target=/usr/share/nginx/html \
    nginx:alpine
   
   
#在主机里使用以下命令可以查看 web 容器的信息
$ docker inspect web
"Mounts": [
    {
        "Type": "bind",
        "Source": "/src/webapp",
        "Destination": "/usr/share/nginx/html",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    }
],

外部访问容器(端口映射)
  • 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P-p 参数来指定端口映射。
# 使用 hostPort:containerPort 格式本地的 80 端口映射到容器的 80 端口
$ docker run -d -p 80:80 nginx:alpine
容器互联
# 创建一个新的 Docker 网络。
$ docker network create -d bridge my-net

# 运行一个容器并连接到新建的 my-net 网络
$ docker run -it --rm --name busybox1 --network my-net ubuntu /bin/bash

# 打开新的终端,再运行一个容器并加入到 my-net 网络
$ docker run -it --rm --name busybox2 --network my-net ubuntu /bin/bash


#下面通过 ping 来证明 busybox1 容器和 busybox2 容器建立了互联关系。
#在 busybox1 容器输入以下命令
$  ping busybox2
PING busybox2 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.072 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.118 ms

#用 ping 来测试连接 busybox2 容器,它会解析成 172.19.0.3。
#同理在 busybox2 容器执行 ping busybox1,也会成功连接到。
$  ping busybox1
PING busybox1 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.064 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.143 ms

下面是一个包含指定ip地址的方式,这种方式也是可以实现容器互联的

# 创建一个network
sudo docker network create -d macvlan  --subnet=192.168.124.0/24 --gateway=192.168.124.1 -o parent=ens33 mynet

# 在这个网络里创建容器
sudo docker run --net=mynet --ip=192.168.124.121  -it --rm ubuntu /bin/bash

其它

在apple M1上构建x86_64 Docker镜像

  • docker镜像能跨平台运行;只要系统架构一样,是可以使用相同的镜像的,x86的镜像只能在x86系统使用,arm的镜像只能在arm系统使用,docker镜像对容器而言只是模拟了一个环境,与宿主机的关系不大。Docker镜像是操作系统相关的,外面所谓的build once run anywhere是有前提条件的,是在Linux这个操作系统族内才生效。

参考资料

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值