[Note] Docker 使用记录

165 阅读9分钟

Docker

Get Docker | Docker Docs

安装

[安装Docker | Raspberry Pi 树莓派 (官网24年12月更新)](https://pidoc.cn/docs/pidoc/install_docker)
  1. 安装之前需要删除旧版本和非官方版本 Docker Engine 依赖 containerd and runc,被打包成一个 bundle, 如果之前安装过,,则需要卸载,避免版本冲突。
#安装前先卸载操作系统默认安装的docker,
sudo apt-get remove docker docker-engine docker.io containerd runc

#安装必要支持
sudo apt install apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release
执行下面的命令,移除之前安装
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
  • docker.io
  • docker-compose
  • docker-compose-v2
  • docker-doc
  • podman-docker

Images, containers, volumes, and networks stored in /var/lib/docker/ 不会被自动卸载. 如果想安装干净版本, 推荐删除,相关说明文档章节 uninstall Docker Engine .

  1. 初试化 docker 的 apt repo 使用 apt 安装之前,需要配置初始化 docker 的 apt repo,后续安装和更新都来自这个 repository
#添加 Docker 官方 GPG key (可能国内现在访问会存在问题)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 阿里源(推荐使用阿里的gpg KEY)
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

#添加 apt 源:
#Docker官方源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

#阿里apt源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

#更新源
sudo apt update
sudo apt-get update
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$UBUNTU_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

If you use an Ubuntu derivative distribution, such as Linux Mint, you may need to use UBUNTU_CODENAME instead of VERSION_CODENAME.

  1. 安装 docker 依赖库
#安装最新版本的Docker
sudo apt install docker-ce docker-ce-cli containerd.io
#等待安装完成

#查看Docker版本
sudo docker version

#查看Docker运行状态
sudo systemctl status docker

# 安装Docker 命令补全工具
sudo apt-get install bash-completion

sudo curl -L https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh

source /etc/bash_completion.d/docker.sh
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 安装验证
sudo docker version
sudo systemctl status docker
sudo docker run hello-world

设置国内源

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
{
    "registry-mirrors": [
        "https://docker.linkedbus.com",
        "https://docker.xuanyuan.me",
        "https://docker.m.daocloud.io"
    ]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

image.png

docker-compose

另一个重要组件是 Docker Compose。请记住,它是与 Docker 分开提供的。因此,在添加Docker Compose之前必须先安装Docker;否则,Compose 将无法运行。

安装它非常简单,即使您的 Linux 系统上尚未安装它。要安装 Docker Compose,请键入以下两个命令:

sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m)" -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

docker 命令大全

容器生命周期管理

容器操作

容器的root文件系统(rootfs)命令

镜像仓库

本地镜像管理

info|version

Docker Compose

网络命令

  • docker network ls: 列出所有网络。
  • docker network create <network> : 创建一个新的网络。
  • docker network rm <network> : 删除指定的网络。
  • docker network connect <network> <container> : 连接容器到网络。
  • docker network disconnect <network> <container> : 断开容器与网络的连接。

详细内容查看:docker network 命令

卷命令

  • docker volume ls: 列出所有卷。
  • docker volume create <volume> : 创建一个新的卷。
  • docker volume rm <volume> : 删除指定的卷。
  • docker volume inspect <volume> : 显示卷的详细信息。

强制 Kill Container

遇到无法 kill container 时,可以依次尝试下面几种方式:

  1. 重启 Docker Service Restarting the Docker service can often resolve this issue by resetting the Docker daemon and its processes
sudo systemctl restart docker

2. Kill the Container Process Manually

If restarting Docker doesn't work, you can manually kill the container's process

  • Find the process ID (PID) of the container:
ps aux | grep $(docker container ls -q --filter 'name=<container-name>') | awk '{print $2}'
  • Kill the process using kill -9:
sudo kill -9 <pid>

3. Remove AppArmor Profiles (if applicable)

AppArmor profiles can sometimes interfere with Docker containers. Disabling AppArmor might help

sudo systemctl disable apparmor

sudo service apparmor teardown

4. Restart Host Machine

As a last resort, restarting the host machine can clear any lingering issues that prevent the container from stopping

By following these steps, you should be able to resolve the issue and successfully stop or kill your Docker container.

四种网络模式

在docker平台里有四种网络模式,今天继续分享一下它们的常用知识,进一步加深对docker技术的理解。

1、docker网络模式分类

docker run创建Docker容器时,可以用--net选项指定容器的网络模式,Docker主要有以下4种网络模式。

  • bridge模式:--net=bridge 桥接模式(默认设置,自己创建也使用bridge 模式)
  • host模式:--net=host 和宿主即共享网络
  • container模式:--net=container:NAME_or_ID 容器网络连通!(很少用,局限性很大!)
  • none模式:--net=none 不配置网络

查看所有的docker网络

命令:docker network ls

[root@iZwz9535z41cmgcpkm7i81Z ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
8ddb7e9846c6   bridge    bridge    local
48e785b7efb3   host      host      local
7e07c5b5ae34   none      null      local

2、bridge 网桥模式

Docker安装启动后会在宿主主机上创建一个名为 docker0 的虚拟网桥,处于七层网络模型的数据链路层,后续每当我们创建一个新的docker容器,在不指定容器网络模式的情况下,docker会通过 docker0 与主机的网络连接,docker0 相当于网桥。

使用 bridge 模式新创建的容器,容器内部都会有一个虚拟网卡,名为 eth0,容器之间可以通过容器内部的IP相互通信。

命令:docker run -d -name tomcat01 --net=bridge -p 8085:80 tomcat:latest
说明:

  • --net=bridge 可省略 ,-p 指定端口映射
  • 网桥默认 IP 范围是一般都是 172.17.x.x

3、host 模式

如果指定的host模式容器不会拥有一个独立network namesace,而是与宿主主机共用network namesace。也就说明容器本身不会有的网卡信息,而是使用宿主主机的网络信息。容器除了网络,其他比如文件系统、进程等依然都是隔离的。

说明:

  • --net=host 指定
  • 容器和宿主主机共享 Network namespace
  • host模式因为和宿主主机共享network namespace,会有可能出现端口冲突的情况。

4、container模式

container模式和host模式很类似,host模式和宿主主机共享network namespace;container模式和指定的容器共享,两者之间除了网络共享(网卡、主机名、IP 地址),其他方面还是隔离的。

命令:docker run -d -name tomcat02 --net=container:name/id -p 8000:80 tomcat:latest
说明:

  • –-net={容器id 或容器name} 指定
  • 当前容器和另外一个容器共享 Network namespace

5、none模式

如果dockers容器指定的网络模式为none,该容器没有办法联网,外界也无法访问它,可以用来本次测试。

命令:docker run -d -name tomcat02 --net=none -p 8000:80 tomcat:latest
说明:

  • --net=none 指定
  • 容器有独立的Network namespace,但并没有对其进行任何网络设置,如果需要的话,需要自定义配置网络

Docker 网络桥接模式和 Host 模式的区别

首先,我们需要了解一下 Docker 的两种网络模式之间的区别。在桥接网络模式下,Docker 将为每个容器创建一个独立的网络命名空间,并为容器分配一个|P 地址。而在 Host 网络模式下,容器将直接使用主机的网络栈,与主机共享网络接口和 IP 地址,这意味着容器可以直接访问主机上的所有网络服务,同时也会导致容器与主机网络之间的隔离性降低。

Docker 网络桥接改 Host

在使用 Docker 运行容器时,经常会涉及到网络配置。默认情况下,Docker 使用桥接网络模式来为容器提供网络连接。但有时候,我们可能需要将容器直接连接到主机的网络,这时就需要将 Docker 网络模式改为 Host 模式。在本文中,我们将介绍如何通过改变 Docker 网络桥接模式为 Host 模式来实现容器直接连接到主机网络的配置。

Docker 容器不能直接修改已创建的网络模式为 host。但是,你可以通过以下步骤来实现你的需求:

1. 停止当前运行的容器。
2. 删除原有的容器。
3. 重新创建并指定网络模式为 host。

以下是一些可能的解决方案:

解决方案1:使用命令行

# 停止当前运行的容器
docker stop <container_id>
 
# 删除原有的容器
docker rm <container_id>
 
# 重新创建并指定网络模式为 host
docker run --net=host --name=<container_name> <image_name>

解决方案2:使用Docker Compose
如果你使用Docker Compose来管理你的容器,你可以在你的docker-compose.yml文件中更改网络模式,然后重新创建你的服务。

version: '3'
services:
  your_service:
    image: your_image
    network_mode: host

然后运行以下命令来重新创建服务:

docker-compose up -d

注意:使用 host 网络模式的容器将会使用宿主机的网络,这意味着容器的网络配置和DNS设置将与宿主机相同。这可能会导致网络配置冲突,因此在使用 host 网络模式前,请确保这是你想要的行为

使用Docker进入容器并执行Bash命令的详细指南

Docker作为现代软件开发中不可或缺的工具,极大地简化了应用的部署和管理。无论是开发、测试还是生产环境,Docker容器都提供了高度一致和可移植的环境。本文将详细介绍如何使用Docker进入容器并执行Bash命令,帮助读者更好地理解和操作Docker容器。

二、进入Docker容器的方法

进入Docker容器主要有两种方法:docker execdocker attach。本文将重点介绍docker exec,因为它更灵活且不会干扰容器的主进程。

2.1 使用docker exec

docker exec命令允许在已经运行的容器中启动新的进程,相当于在容器内部开启一个新的终端。

基本语法

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

常用选项

  • -i:保持标准输入打开。
  • -t:分配一个伪终端。
  • -u:指定用户身份。

示例

docker exec -it mycontainer /bin/bash

这条命令会进入名为mycontainer的容器,并启动一个Bash shell。

2.2 使用docker attach

docker attach命令用于连接到正在运行的容器,但它会直接连接到容器的主进程,可能会导致一些不便。

基本语法

docker attach [OPTIONS] CONTAINER

示例

docker attach mycontainer

这条命令会直接连接到mycontainer的主进程。

三、docker exec命令详解

docker exec命令非常强大,不仅可以启动Bash shell,还可以执行其他命令。

3.1 进入交互式终端

示例

docker exec -it mycontainer /bin/bash

这条命令会进入容器的交互式终端,你可以像在普通Linux系统中一样执行命令。

3.2 执行单个命令

如果你只需要执行一个命令而不进入交互式终端,可以省略-it参数。

示例

docker exec mycontainer ls -a

这条命令会在mycontainer中执行ls -a,列出所有文件和目录。

3.3 使用bash -c执行复杂命令

有时你可能需要执行一系列复杂的命令,这时可以使用bash -c

示例

docker exec -it mycontainer bash -c "echo 'Hello, World!' && ls -a"

这条命令会在mycontainer中先输出Hello, World!,然后列出所有文件和目录。

四、Python封装docker exec命令

为了更灵活地使用docker exec,我们可以用Python进行封装。

示例代码

import subprocess

def execute_in_container(container_name, command):
    full_command = f"docker exec -it {container_name} bash -c '{command}'"
    result = subprocess.run(full_command, shell=True, text=True, capture_output=True)
    return result.stdout

# 使用示例
output = execute_in_container("mycontainer", "echo 'Hello, World!' && ls -a")
print(output)

这个Python函数execute_in_container接受容器名称和命令作为参数,执行命令并返回输出结果。

五、注意事项

在使用docker exec时,需要注意以下几点:

  1. 准确指定容器名称或ID:确保容器名称或ID正确,否则命令会失败。
  2. 执行命令的谨慎性:在容器内执行命令时要谨慎,避免对容器造成不必要的破坏。
  3. 容器内用户的权限:根据需要使用-u参数指定用户身份,避免权限问题。
  4. 命令的操作系统和环境兼容性:确保命令在容器的操作系统和环境中是兼容的。
  5. 处理命令执行错误:妥善处理命令执行过程中可能出现的错误。

六、常见问题解答

Q1:为什么docker execdocker attach更推荐?

A1:docker exec可以在不干扰主进程的情况下启动新的进程,而docker attach会直接连接到主进程,可能导致一些不便。

Q2:如何以非root用户身份进入容器?

A2:使用-u参数指定用户身份,例如docker exec -u myuser -it mycontainer /bin/bash

Q3:容器中没有Bash怎么办?

A3:可以使用其他shell,如/bin/sh,例如docker exec -it mycontainer /bin/sh