Docker 笔记

| 分类 utilities  | 标签 docker 

常用命令

以下说的 container,即 container_name 或者 container_id 都可以。containers 即可以是多个容器。

# 查看 docker 状态
docker info


# 容器相关
# 不加 -a 参数只能看到正在运行的容器
docker container ls -a / docker ps -a(效果一样)
# 通过容器名,或者 ID ,启动/重启/停止/删除容器
docker container {start/restart/stop/rm} container_name[or container_id]
docker rm $(docker ps -a -q)	# 删除所有容器
# 查看容器内的进程
docker top container_id
# 在容器外,向容器内发出命令。交互式运行
docker exec -it container_id /bin/bash(container_id 之后直接跟命令)
# 将容器中的文件复制到本地
docker container cp container_id:/path /host-path


# 镜像相关
# 查看所有的镜像,不加 -a 只能看到可用的镜像
docker images -a
# 拉取指定版本的镜像
docker pull ubuntu:12.04
# 查看构建镜像的历史信息
docker history image_id
# 删除镜像
docker rmi image_id
# 遇到相同 ImageId 的镜像,删除不想要的镜像仓库
docker image rm REPOSITORY:TAG
# 删除所有镜像
docker rmi $(docker images -q)


# 不常用的命令
# 查看多个容器的统计信息
docker stats containers
# 指定运行进程的所有者
docker exec -u root container
# 强制关闭容器
docker kill container
# 获取更详细的配置信息
docker inspect container
# 查看容器和主机的端口绑定关系
docker ps -l
docker port container container_port
# 登陆 docker hub
docker login
# 退出 docker hub
docker logout

run 命令

docker run --restart=always --name NewName -d -i -t -p 4000:80 --link db:db ubuntu:12.04 /bin/bash

命令解释:

参数 解释
--name 给容器指定一个名字
-i 开启容器的 stdin,-i -t 一起使用,才能为容器提供一个交互式 shell
-t 为创建的容器分配一个伪 tty 终端
--restart=always 由于某种错误而导致容器停止运行,通过这个参数可以自动重启容器
--restart=failure:5 只有当容器的推出代码为非0值是,才自动重启容器,重启次数为5次
-p 4000:80 将docker容器的80端口,映射到宿主机的4000端口上
--link db:db 连接别的docker容器,参数是:<容器名称>:<别名>。
这种方式可以连接同一台主机上的不同docker容器。
-d 在后台运行一个守护式容器
--log-driver 日志选项,默认是:json-file,
可以选择 --log-driver=”syslog”,将所有日志重定
向到系统日志。也可以选择none,仅用日志。
ubuntu:12.04 标签12.04是指镜像 ubuntu 的特定版本。
如果不加标签则下载 latest 标签的镜像

logs 命令

# 获取容器日志
docker logs container
# 监控日志
docker logs -f container
# 获取最后10条日志
docker logs --tail 10 container
# 跟踪最新的日志,而不必读取整个日志文件
docker logs --tail 0 -f container
# 给日志加上时间戳
docker logs -ft container

创建镜像命令与提交 docker hub

# 基于 Dockerfile 文件构建新镜像,并指定名字为 static_web
docker build -t="vincen666/static_web" .
# 如果构建失败,第二次构建时,忽略之前构建的缓存
docker build --no-cache -t="vincen666/static_web" .
docker login
# 给镜像打 tag
docker tag <image> username/repository:tag
# Upload tagged image to registry
docker push username/repository:tag
# Run image from a registry
docker run username/repository:tag

Dockerfile

格式

<指令> <参数>

命令必须是大写。第一个命令一定是FROM。每一条命令都是独立运行的。命令是顺序执行的。

.dockerignore

Dockerfile 文件所在的目录即 docker 的“上下文”(context)。在这个目录中的所有文件都会传到 Docker 守护进程。可以使用 .dockerignore 文件来忽略不想要的目录和文件。文件的匹配模式见:go filepath Match

指令

Dockerfile中的指令

RUN, CMD, ENTRYPOINT 比较

RUN: 用于在 FROM 中设置的镜像上运行脚本或命令。RUN 运行结果会生成新的镜像,运行的详细信息记录到镜像历史中。

CMD: 用于设置容器启动时运行的脚本或命令。在 Dockerfile 只能设置一次,如果设置多个,只会执行最后一个。CMD 类似于 docker run 启动容器时的命令。

ENTRYPOINT: 用于设置容器启动时运行的脚本或命令。也只能设置一次。

CMD 版 Dockerfile

FROM ubuntu CMD [“echo”, “hello”]

运行时指定一个可执行命令:

sudo docker run container echo world

因为 docker run 设置的可执行命令会覆盖 CMD 指令,所以忽略 CMD 指令(不是因为 CMD 指令是 echo hello,其他的命令照样忽略),输出:world

ENTRYPOINT 版 Dockerfile:

FROM ubuntu ENTRYPOINT [“echo”, “hello”]

sudo docker run container echo world

虽然给 docker run 设置了可执行命令,但是并不会忽略 ENTRYPOINT 指令。而且,还会把设置的可执行命令作为参数,传递给 ENTRYPOINT。输出:hello echo world

若在 docker run 命令中设置了 --entrypoint 参数,则会忽略 Dockerfile 中的 ENTRYPOINT 指令。

ADD & COPY

ADD 指令添加本地压缩文件 hello.tar.gz,会解压缩,并将tar拆包。

但是添加网络文件时,只进行解压缩,不会将tar拆包。需要自己拆包。

COPY 不能添加网络文件,也不会进行解压缩和拆包这两个动作。

最佳实践

从容器内访问宿主机上的服务

If you are using Docker-for-mac or Docker-for-Windows 18.03+, just connect to your mysql service using the host host.docker.internal (instead of the 127.0.0.1 in your connection string).

If you are using Docker-for-Linux 20.10.0+, you can also use the host host.docker.internal if you started your Docker container with the --add-host host.docker.internal:host-gateway option.

Otherwise, read below: https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach

修改容器内系统的时间

使用 docker 容器部署的应用,会出现时间与主机不一致的情况,是因为 Linux 系统默认是 GMT 的时区。中国时区是 GMT+8

将本机的 localtime 文件,拷贝到容器中的操作系统,然后重启即可解决。

cp /etc/localtime container_name:/etc/localtime

连接不同主机上的容器

Ambassador Pattern

使用ambassador容器,代理连接多台主机上的容器

数据卷容器

数据卷

使用如下命令将一个或多个容器的目录挂载到当前主机的目录上,在容器和主机间目录的内容都是共享的。

docker run -i -t -v /root/data:/data ubuntu /bin/bash

即把容器的/data目录挂载到当前主机的/root/data目录下。

Import: 不要期望 docker 把数据给你存到容器内部,实际上数据都是在主机的 /var/lib/docker/vfs/dir/xxxx 的目录下。当然如果你的主机是 Ubuntu 系统,docker 会使用 aufs 文件系统,那么目录就是:/var/lib/docker/aufs/diff/xxxx。由于没有名称,都是些类似以 uuid 为名字的目录,所以,数据还是放在数据卷中最好。

数据卷容器

数据卷容器就是个普通容器,其实就是提供了一个公共的地方映射数据。

容器A:/data ---->	
                  数据卷容器:/data(数据卷) ----> /root/data
容器B:/data ---->
# 创建数据卷容器
docker run -i -t --name base-volume -v /root/data:/data ubuntu /bin/bash
# 创建容器A,并挂载到数据卷容器
docker run -d --volume-from base-volume --name containerA ubuntu
# 创建容器B,并挂载到数据卷容器
docker run -d --volume-from base-volume --name containerB ubuntu

alpine 镜像的特殊操作

# alpine 使用的是 ash shell
docker exec -it alpine /bin/ash

# 修改成阿里源
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# 更新源
apk update
# 安装 ssh
apk search openssh
apk add openssh
# 安装rc-service (类似于ubuntu的systemctl)
apk add openrc
# 设置 openrc,不加入这一行,open rc 无法正常工作
touch /run/openrc/softlevel

阿里镜像仓库

REPOSITORY TAG DESCRIPTION
ubuntu v1 BASE: ubuntu 20.04
阿里源
curl
openssh-server
jupyter    
node v16 npm@8.5.4
@angular/cli@13.2.6
typescript@4.6.2
     
     
     
     
     
     
     

上一篇     下一篇