Docker

Docker

什么是 Docker

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

安装

官方文档 - Install Docker Engine on Ubuntu

删除旧版本

1
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done

apt 安装

设置 Docker 的 apt 存储库

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 添加 Docker 官方 GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# 添加 apt 源:
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 更新
sudo apt-get update

安装

1
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

下载 hello-world 镜像验证

1
sudo docker run hello-world

脚本一键安装

1
2
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

将当前用户加入 docker 组: #Got permission denied

使用

基本命令

1
2
3
4
5
6
7
8
9
# 显示 Docker 版本信息
sudo docker version

# 显示整个系统的信息
sudo docker info

# 命令帮助
sudo docker help
sudo docker COMMAND --help
docker 命令帮助 ``` Usage: docker [OPTIONS] COMMAND A self-sufficient runtime for containers Options: ​ --config string Location of client config files (default "/home/ubuntu/.docker") -c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use") -D, --debug Enable debug mode -H, --host list Daemon socket(s) to connect to -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") ​ --tls Use TLS; implied by --tlsverify ​ --tlscacert string Trust certs signed only by this CA (default "/home/ubuntu/.docker/ca.pem") ​ --tlscert string Path to TLS certificate file (default "/home/ubuntu/.docker/cert.pem") ​ --tlskey string Path to TLS key file (default "/home/ubuntu/.docker/key.pem") ​ --tlsverify Use TLS and verify the remote ​ -v, --version Print version information and quit Management Commands: app* Docker App (Docker Inc., v0.9.1-beta3) builder Manage builds buildx* Build with BuildKit (Docker Inc., v0.5.1-docker) config Manage Docker configs container Manage containers context Manage contexts image Manage images manifest Manage Docker image manifests and manifest lists network Manage networks node Manage Swarm nodes plugin Manage plugins scan* Docker Scan (Docker Inc., v0.7.0) secret Manage Docker secrets service Manage services stack Manage Docker stacks swarm Manage Swarm system Manage Docker trust Manage trust on Docker images volume Manage volumes Commands: attach Attach local standard input, output, and error streams to a running container build Build an image from a Dockerfile commit Create a new image from a container's changes cp Copy files/folders between a container and the local filesystem create Create a new container diff Inspect changes to files or directories on a container's filesystem events Get real time events from the server exec Run a command in a running container export Export a container's filesystem as a tar archive history Show the history of an image images List images import Import the contents from a tarball to create a filesystem image info Display system-wide information inspect Return low-level information on Docker objects kill Kill one or more running containers load Load an image from a tar archive or STDIN login Log in to a Docker registry logout Log out from a Docker registry logs Fetch the logs of a container pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container ps List containers pull Pull an image or a repository from a registry push Push an image or a repository to a registry rename Rename a container restart Restart one or more containers rm Remove one or more containers rmi Remove one or more images run Run a command in a new container save Save one or more images to a tar archive (streamed to STDOUT by default) search Search the Docker Hub for images start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers version Show the Docker version information wait Block until one or more containers stop, then print their exit codes Run 'docker COMMAND --help' for more information on a command. To get more help with docker, check out our guides at https://docs.docker.com/go/guides/ ```

镜像相关

1
docker images --help
docker images 命令帮助 ``` Usage: docker images [OPTIONS] [REPOSITORY[:TAG]] List images Options: -a, --all Show all images (default hides intermediate images) --digests Show digests -f, --filter filter Filter output based on conditions provided --format string Pretty-print images using a Go template --no-trunc Don't truncate output -q, --quiet Only show image IDs ```
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 查找镜像
docker search golang

# 拉取镜像
docker pull golang
docker pull golang:latest # 指定版本

# 查看已安装镜像
docker images

# 删除镜像
docker rmi golang # 通过镜像名
docker rmi 0ac33e5f5afa # 通过镜像 ID

# 删除全部镜像
docker rmi $(docker images -qa)
# 参数 q(quiet):只显示镜像 ID
# 参数 a(all):显示所有镜像(包括中间镜像)

容器相关

docker run - 在新容器中运行

以交互模式在后台启动一个名为 grafana 的容器,并分配 tty,使用宿主机网络,永远会重启。

1
docker run -itd --net=host --restart=always --name=grafana grafana/grafana
docker run 具体选项 | 选项 | 说明 | | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | -d, --detach=false | 指定容器运行于前台还是后台,默认为 false。 | | -i, --interactive=false | 打开 STDIN,用于控制台交互。 | | -t, --tty=false | 分配 tty 设备,可以支持终端登录,默认为 false。 | | -u, --user="" | 指定容器的用户。 | | -a, --attach=[] | 登录容器(必须是以 docker run -d 启动的容器)。 | | -w, --workdir="" | 指定容器的工作目录。 | | -c, --cpu-shares=0 | 设置容器 CPU 权重,在 CPU 共享场景使用。 | | -e, --env=[] | 指定环境变量,容器中可以使用该环境变量。 | | -m, --memory="" | 指定容器的内存上限。 | | -P, --publish-all=false | 指定容器暴露的端口。 | | -p, --publish=[] | 指定容器暴露的端口。 | | -h, --hostname="" | 指定容器的主机名。 | | -v, --volume=[] | 给容器挂载存储卷,挂载到容器的某个目录。 | | –volumes-from=[] | 给容器挂载其他容器上的卷,挂载到容器的某个目录。 | | –cap-add=[] | 添加权限。 | | –cap-drop=[] | 删除权限。 | | –cidfile="" | 运行容器后,在指定文件中写入容器 PID 值,一种典型的监控系统用法。 | | –cpuset="" | 设置容器可以使用哪些 CPU,此参数可以用来容器独占 CPU。 | | –device=[] | 添加主机设备给容器,相当于设备直通。 | | –dns=[] | 指定容器的 dns 服务器。 | | –dns-search=[] | 指定容器的 dns 搜索域名,写入到容器的 /etc/resolv.conf 文件。 | | –entrypoint="" | 覆盖 image 的入口点。 | | –env-file=[] | 指定环境变量文件,文件格式为每行一个环境变量。 | | –expose=[] | 指定容器暴露的端口,即修改镜像的暴露端口。 | | –link=[] | 指定容器间的关联,使用其他容器的 IP、env 等信息。 | | –lxc-conf=[] | 指定容器的配置文件,只有在指定 --exec-driver=lxc 时使用。 | | –name="" | 指定容器名字,后续可以通过名字进行容器管理,links 特性需要使用名字。 | | –net=“bridge” | 器网络设置: 1. bridge 使用 docker daemon 指定的网桥。 2. host //容器使用主机的网络。 3. container:NAME_or_ID >//使用其他容器的网路,共享 IP 和 PORT 等网络资源。 4. none 容器使用自己的网络(类似–net=bridge),但是不进行配置。 | | –privileged=false | 指定容器是否为特权容器,特权容器拥有所有的 capabilities。 | | –restart=“no” | 指定容器停止后的重启策略: (1) no,容器退出时不重启 (2) on-failure,容器故障退出(返回值非零)时重启 (3) on-failure:3,同上,最多重启 3 次 (4) always,容器退出时总是重启 | | –rm=false | 指定容器停止后自动删除容器(不支持以 docker run -d 启动的容器)。 | | –sig-proxy=true | 设置由代理接受并处理信号,但是 SIGCHLD、SIGSTOP 和 SIGKILL 不能被代理。 |

Dockerfile

什么是 Dockerfile?

{% cq %}Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。{% endcq %}

{% note caution caution %} Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。 {% endnote %}

Docker Compose

Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

Compose 使用有三个步骤:

  • 使用 Dockerfile 定义应用程序的环境
  • 使用 docker-compose.yml 定义构成应用程序的服务,这样他们可以在隔离环境中一起运行
  • 最后,执行 docker-compose up 命令来启动并运行整个应用程序

看一个 docker-compose.yml 文件示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
version: '3'
services:
  web:
  	container_name: dockerdev # 容器名
    build: . # 在本目录构建
    ports:
    	- "15000:5000" # 将容器内的 5000 端口映射到宿主机的 15000 端口
    environment: # 环境变量
    	ACCESS_KEY: admin
    volumes: # 挂载数据卷(冒号前为宿主机目录,后为容器内目录)
    	- .:/code
    	- logvolume01:/var/log
    links: # 链接其他容器
    	- redis
  redis:
    image: redis
volumes: # 数据卷
  logvolume01: {}
1
2
docker-compose up
docker-compose up -d # 后台启动

容器备份

备份

1
docker ps -a

备份 grafana 容器,容器名为 grafana,容器 id 为 ab8adb9ae93d,执行如下命令:

1
docker commit -p ab8adb9ae93d grafana-backup
1
docker images

此时已经有了一个名为 grafana-backup 的镜像。

1
docker save grafana-backup > /home/ubuntu/Download/grafana-backup.tar

恢复

  • 将备份文件上传到需要使用的服务器

  • 导入

1
2
docker load < /home/ubuntu/Download/grafana-backup.tar
docker images

可以看到一个名为 grafana-backup 的镜像,导入成功。

portainer 可视化

1
docker pull portainer/portainer-ce
1
docker volume create portainer_data
1
2
3
4
5
docker run -d -p 8000:8000 -p 9000:9000 \
	--name=portainer --restart=always \
	-v /var/run/docker.sock:/var/run/docker.sock \
	-v portainer_data:/data \
	portainer/portainer-ce

注意

Got permission denied

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json: dial unix /var/run/docker.sock: connect: permission denied

docker 进程使用 Unix Socket 而不是 TCP 端口。而默认情况下,Unix socket 属于 root 用户,需要 root 权限才能访问。

Manage Docker as a non-root user

The Docker daemon binds to a Unix socket, not a TCP port. By default it’s the root user that owns the Unix socket, and other users can only access it using sudo. The Docker daemon always runs as the root user.

If you don’t want to preface the docker command with sudo, create a Unix group called docker and add users to it. When the Docker daemon starts, it creates a Unix socket accessible by members of the docker group. On some Linux distributions, the system automatically creates this group when installing Docker Engine using a package manager. In that case, there is no need for you to manually create the group.

docker docs, Linux post-installation steps for Docker Engine

通过下面几步操作,可以将当前用户加入 docker 组,以后再使用 docker 就不需要输入 sudo 了。

1
2
3
4
5
6
# 将当前用户加入 docker 组
sudo gpasswd -a ${USER} docker
# 更新 docker 组
newgrp docker
# 重启 docker 服务
sudo systemctl restart docker

Reference

Licensed under CC BY-NC-SA 4.0