1.安装

地址:https://docs.docker.com/engine/install/ubuntu/

1.1 安装到乌班图

最新教程:https://docs.docker.com/engine/install/ubuntu/

.1 卸载旧的版本

sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get update

1.2 需要的安装包

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

1.3 添加 GPG 密钥,并添加 Docker-ce 软件源

中国科技大学的 Docker-ce 源(其他源类似):

curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
$(lsb_release -cs) stable"

 报错sudo: add-apt-repository: command not found

sudo apt install software-properties-common

又报错:

apt install software-properties-common Reading package lists... Done Building dependency tree Reading state information... Done The following packages were automatically installed and are no longer required: apport-symptoms python3-automat python3-blinker python3-click python3-colorama python3-configobj python3-constantly python3-debconf python3-debian python3-distupgrade python3-entrypoints python3-hamcrest python3-hyperlink python3-incremental python3-jwt python3-keyring python3-lazr.uri python3-oauthlib python3-problem-report python3-pyasn1 python3-pyasn1-modules python3-secretstorage python3-service-identity python3-simplejson python3-systemd python3-twisted python3-twisted-bin python3-update-manager python3-wadllib python3-zope.interface squashfs-tools Use 'sudo apt autoremove' to remove them. The following additional packages will be installed: python3-certifi python3-requests python3-requests-unixsocket Suggested packages: python3-socks E: Could not read response to hello message from hook [ ! -f /usr/bin/snap ] || /usr/bin/snap advise-snap --from-apt 2>/dev/null || true: Success E: Could not read response to hello message from hook [ ! -f /usr/bin/snap ] || /usr/bin/snap advise-snap --from-apt 2>/dev/null || true: Success

看起来您在运行 `sudo apt install software-properties-common` 命令时遇到了问题。根据错误消息,似乎与 Snap 包管理器有关。

您可以尝试以下解决方案:

1. 清除 apt 缓存并重新加载包列表:
   

sudo rm -r /var/lib/apt/lists/*
sudo apt update


 

2. 执行以下命令来安装 `software-properties-common` 包:
 

sudo apt-get install --reinstall software-properties-common

 

如果上述解决方案仍然无效,请尝试禁用 Snap 集成的 APT 钩子,然后重新运行安装命令:

1. 打开 `/etc/apt/preferences.d/nosnap.pref` 文件:
   ```
   sudo nano /etc/apt/preferences.d/nosnap.pref
   ```

2. 在文件中添加以下内容并保存:
   ```
   Package: snapd
   Pin: release a=*
   Pin-Priority: -10
   ```

3. 运行以下命令以卸载 Snap:
   ```
   sudo apt remove --purge snapd
   ```

4. 重新加载包列表并尝试再次安装 `software-properties-common` 包:
   ```
   sudo apt update
   sudo apt install software-properties-common
   ```

如果仍然遇到问题,建议您检查系统配置、软件源设置或寻求进一步的操作系统支持来解决此问题。

 

#注意:添加错了可以用以下命令删除
#查询keyid,下图
sudo apt-key list
#keyid 就是90那一串
sudo apt-key del <keyid>
#加参数-r可以移除
sudo add-apt-repository -r "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update

1.4 安装 Docker-ce

sudo apt-get install docker-ce

安装成功后重启docker

systemctl restart docker

报错:System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down

根据您提供的错误消息,看起来您的系统未使用 systemd 作为 init 系统,因此无法执行 systemctl restart docker 命令。

这通常发生在 WSL (Windows Subsystem for Linux) 或其他特殊环境中,因为这些环境可能不支持 systemd。

要重启 Docker 服务,您可以尝试以下方法之一:

  1. 使用 service 命令:

sudo service docker restart

 

1.5测试运行

sudo docker run hello-world

成功如下

Hello from Docker!
This message shows that your installation appears to be working correctly.

1.2安装到win11

下载安装
阿里云提供的下载地址:http://mirrors.aliyun.com/docker-toolbox/windows/docker-for-windows

官网:https://www.docker.com 进去后点击右上角的Get Started,然后选择相应的版本下载就行


另外一个地址:Docker Desktop: The #1 Containerization Tool for Developers | Docker

控制面板首先开启Hyper-V

安装docker并运行,成功后的样子:绿色

安装出错
1、安装完成后报错:
WSL 2 installation is incomplete.

请点击他提供的网址,然后下载下图中的文件

下载完成后得到的文件,直接双击安装就行

之后重启docker

2、若还是有问题:
System.InvalidOperationException:Failed to set version to docker-desktop: exit code: -1

以管理员身份打开PowerShell,运行命令:

netsh winsock reset

 

运行命令后,重启电脑。然后重新打开docker
点击Start,开始一步一步运行下面蓝色框提供的命令,也可以直接跳过

运行完成后根据提示打开一个链接:

这是docker的使用教程

配置阿里云镜像
在系统右下角托盘图标内右键菜单选择Settings,打开配置窗口后左侧导航菜单选择 Docker Engine。编辑窗口内的JSON串,填写下方加速器地址:

{
  "registry-mirrors": ["https://rgvvbu.mirror.aliyuncs.com"]
}



编辑完成后点击 Apply 保存按钮,等待Docker重启并应用配置的镜像加速器。

配置完成。
1.3 安装到树莓派

在树莓派上安装Docker是相对简单的,以下是一些步骤来安装Docker:

  1. 更新系统

    在安装Docker之前,请确保您的树莓派系统是最新的。打开终端并运行以下命令:

    sudo apt update
    sudo apt upgrade
  2. 安装依赖项

    安装Docker所需的一些依赖项。运行以下命令:

    sudo apt install -y apt-transport-https ca-certificates software-properties-common
  3. 添加Docker的官方GPG密钥

    运行以下命令以添加Docker官方的GPG密钥:

    curl -fsSL https://download.docker.com/linux/raspbian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
  4. 添加Docker APT仓库

    树莓派使用Raspbian操作系统,您需要将Docker的APT仓库添加到系统中。运行以下命令:

    echo "deb [arch=armhf signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/raspbian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    请注意,上述命令中的 armhf 是针对树莓派的32位系统。如果您的树莓派使用64位系统,则将 armhf 替换为 arm64

  5. 更新APT包列表

    运行以下命令以更新APT包列表:

    sudo apt update
  6. 安装Docker

    安装Docker引擎。运行以下命令:

    sudo apt install -y docker-ce docker-ce-cli containerd.io
  7. 启用Docker服务

    启动并启用Docker服务,以便它在系统启动时自动运行:

    sudo systemctl enable docker
    sudo systemctl start docker
  8. 验证安装

    运行以下命令来验证Docker是否正确安装:

    sudo docker --version

    如果成功安装,它将显示Docker的版本信息。

现在,您已经在树莓派上成功安装了Docker。您可以使用Docker来运行容器化的应用程序和服务。请注意,您需要在树莓派上使用sudo权限来运行Docker命令,或将用户添加到docker用户组以允许无需sudo权限来运行Docker命令。

1.4 Debian 安装

在中国,你可以参考以下中文教程来在 Debian 12 上安装 Docker:(2024-07-25)

sudo apt install curl
sudo apt install gpg

1. 导入 Docker 仓库的 GPG 公钥

请运行以下命令来导入 Docker 仓库的 GPG 公钥:

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor | sudo tee /usr/share/keyrings/docker-archive-keyring.gpg > /dev/null

如果一直卡住失败,可以下载本地sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg gpg 

或者用wget 

sudo wget -qO - https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor | sudo tee /usr/share/keyrings/docker-archive-keyring.gpg > /dev/null

2. 更新 APT 源文件以使用 GPG 密钥

确保 Docker 的 APT 源文件引用了正确的密钥:

编辑 /etc/apt/sources.list.d/docker.list 文件,您可以使用以下命令:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian $(lsb_release -sc) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

3. 更新软件包列表

更新 APT 软件包列表:

sudo apt update

4. 安装 Docker

尝试再次安装 Docker:

sudo apt install docker-ce docker-ce-cli containerd.io

通过这些步骤,您应该能够成功导入 GPG 公钥,并配置 Docker 的 APT 源。如果仍然有问题,请提供新的错误信息。

1.5 Armbian (Ubuntu 22.04 Jammy)安装

✔️ 1. 安装依赖组件

sudo apt install -y ca-certificates curl gnupg lsb-release

✔️ 2. 添加 Docker GPG 密钥

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

✔️ 3. 添加 Docker 软件源(使用阿里云镜像)

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

✔️ 4. 更新并安装 Docker 组件

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

✔️ 5. 启动并设置开机自启

sudo systemctl enable docker
sudo systemctl start docker

✔️ 6. 验证安装成功

docker --version

输出应该类似于:

Docker version 24.x.x, build xxxxx

2.可以用阿里云加速,腾讯云带预测

http://www.bubuko.com/infodetail-3410473.html

登录阿里云后,访问https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors,会看到加速器地址,复制下来,执行后面的命令。(root登录时不需加sudo)

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://s7szypb5.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

3. 帮助文档https://docs.docker.com/reference/

3.1 镜像命令

网址:https://docs.docker.com/engine/reference/commandline/images/

  • 查看主机上的映像
sudo docker images

REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
hello-world   latest    d1165f221234   2 weeks ago   13.3kB

 

  • docker search 镜像搜索
sudo docker search mysql

搜索过滤:搜索stars大于3000的MySQL

sudo docker search mysql --filter stars=3000

下载镜像:docker pull 镜像名[:tag](默认最新版的)

sudo docker pull mysql

Using default tag: latest  # 如果不写tag默认latest
latest: Pulling from library/mysql
6f28985ad184: Pull complete  # 分层下载docker image 的核心,来拟合文件系统
e7cd18945cf6: Pull complete 
ee91068b9313: Pull complete 
b4efa1a4f93b: Pull complete 
f220edfa5893: Pull complete 
74a27d3460f8: Pull complete 
2e11e23b7542: Pull complete 
fbce32c99761: Pull complete 
08545fb3966f: Pull complete 
5b9c076841dc: Pull complete 
ef8b369352ae: Pull complete 
ebd210f0917d: Pull complete 
Digest: sha256:5d1d733f32c28d47061e9d5c2b1fb49b4628c4432901632a70019ec950eda491  # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest  # 真实地址

如果指定版本docker pull mysql:8.0

3.1.1 删除镜像

docker rmi -f  镜像或id

yys@yys:~$ sudo docker images 
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
mysql         latest    26d0ac143221   34 hours ago   546MB
hello-world   latest    d1165f221234   2 weeks ago    13.3kB

sudo docker rmi -f 26d0ac143221

删除多个容器(用空格)

sudo docker rmi -f 容器1 容器2 容器3

删除全部容器
sudo docker rmi -f $(docker images - ap)

报错

Error response from daemon: conflict: unable to delete c8562eaf9d81 (cannot be forced) - image is being used by running container 05767b4a14dd

解决:

执行命令docker ps -a
该命令的含义是查看所有的容器,包括未运行的容器.
通过执行该命令,可以看到,有一个容器引用了该镜像

执行命令docker rm eca596ce0f9d 删除该容器. 其中eca596ce0f9d为容器的id

 

# Delete all containers 删除容器

docker rm -f $(docker ps -a -q) 

# Delete all images

docker rmi -f $(docker images -q)

 

 3.1.2 把普通用户加入到docker组中 

     这里的普通用户是huali,组docker在安装docker的时候,就已经添加了,所以只需要执行两个操作即可:
    

sudo gpasswd -a $USER docker 


    

newgrp docker


3.2 容器命令

下载一个容器

sudo docker pull centos

docker run [可选参数] image

# 参数说明

--name="Name" 容器名字 tomcat01 tomcat02, 用来区分容器

-d                        后台方式运行

-it                         使用 交互式方式运行,进入容器查看内容

-p                         指定容器端口 -p 8080:8080

        -p ip:主机端口:容器端口

        -p  主机端口:容器端口(常用)

        -p 容器端口

-p 随机指定端口

启动并进入容器

sudo docker run  -it centos /bin/bash

推出容器

exit

显示正在运行的容器

docker ps

查看曾经运行过的

docker ps -a

容器不停止推出

ctrl+P+Q

启动和停止容器的操作

 docker start容器id #启动容器

 docker restart容器id #重启容器

 docker stop容器id #停止当前正在运行的容器

 docker kill容器id #强制停止当前容器

查看日志

 docker logs -f -t--tail 容器,没有日志

#自己编写一段she11脚本

sudo docker run -d centos /bin/sh -c "while true; do echo yys; sleep 1; done"
docker ps

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
ca2503e51c11   centos    "/bin/sh -c 'while t…"   15 seconds ago   Up 11 seconds             peaceful_kilby

#显示日志

sudo docker logs -tf --tail 10 ca2503e51c11

查看容器中进程信息

docker top 容器id

sudo docker top ca2503e51c11

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                38365               38345               0                   19:15               ?                   00:00:00            /bin/sh -c while true; do echo yys; sleep 1; done
root                38902               38365               0                   19:21               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1

查看镜像的元数据

sudo docker inspect ca2503e51c11

进入当前正在运行的容器

#方式一

#我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置

#命令

 docker exec -it 容器 id bashshe11

sudo docker exec -it ca2503e51c11 /bin/bash

#方式二

 docker attach容器id

#测试

 [rootakuangshen /]  docker attach dce7b86171bf

正在执行当前的代码

# docker exec #进入容器后开启一个新的终端,可以在里面操作(常用)

# docker attach #进入容器正在执行的终端,不会启动新的进程

从容器内拷贝文件到主机上

 docker cp容器id:容器内路径目的的主机路径

在docker home目录下新建一个test.py

然后退出

下面命令列出最近运行的docker

sudo docker ps -a

然后复制

sudo docker cp f76e0b7e1c20:/home/test.py /home

 

Docker安装 Nginx

#1、搜索镜像 search建议大家去 docker搜索,可以看到帮助文档

#2、下载镜像pu11

#3、运行测试

sudo docker pull nginx

# -d后台运行

# --name给容器命名

# -p宿主机端口:容器内部端口

sudo docker run -d --name nginx01 -p 3344:80 nginx

curl localhost:3344

 

 

Docker commit 命令


docker commit :从容器创建一个新的镜像。

语法

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

OPTIONS说明:

  • -a :提交的镜像作者;

     

  • -c :使用Dockerfile指令来创建镜像;

     

  • -m :提交时的说明文字;

     

  • -p :在commit时,将容器暂停。

 

3.容器数据券的使用


方式一:直接使用命令来挂载-V

sudo docker run -it -v /home/ceshi:/home centos /bin/bash

在乌班图下home下会多个测试文件夹,centos里面可以自动同步到外面乌班图

sudo docker inspect 0667eef89006

可以看到挂载上了

"Mounts": [
            {
                "Type": "bind",
                "Source": "/home/ceshi",      //乌班图路径
                "Destination": "/home",   //容器centos 路径
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

在任何一个目录下新建文件都是同步的 

 

再来测试!

1、停止容器

2、宿主机上修改文件

3、启动容器

4、容器内的数据依旧是同步的!

好处:我们以后修改只需要在本地修改即可,容器内会自动同步!

 

 

-d后台运行

-p端口映射

-卷挂载

-e环境配置

--name容器名字

sudo docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql01 mysql:8.0

 

我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用的具名挂载

#如何确定是具名挂载还是匿名挂载,还是指定路径挂载!

-v 容器内路径匿名挂载

-v卷名:容器内路径 #具名挂载

-V 宿主机路径::容器内路径 #指定路径挂载!

 

数据卷Dockerfile

在home 目录下新建一个文件夹docker-test-volume

新建一个文件编辑内容

sudo vim dockerfile1
FROM centos
VOLUME ["volume01", "volume02"]

CMD echo "----end----"
CMD /bin/bash
docker build -f /home/docker-test-volume/dockerfile1 -t yys/centos:1.0 .

会发现多了一个自定义镜像

yys@yys:/home/docker-test-volume$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
yys/centos   1.0       de0d3f247631   2 minutes ago   209MB
mysql        latest    c8562eaf9d81   2 months ago    546MB
centos       latest    300e315adb2f   3 months ago    209MB

 

DockerFile

这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像!
假设构建镜像时候没有挂载卷,要手动镜像挂载-卷名:容器内路径
 dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写 dockerfile文,这个文件十分简单!
 Docker镜像逐渐成为企业交付的标准,必须要掌握!
步骤:开发,部署,运维。。缺一不可!
 DockerFile:构建文件,定义了一切的步骤,源代码
 Dockerlmages:通过 DockerFile构建生成的镜像,最终发布和运行的产品
 Docker容器:容器就是镜像运行起来提供服务器 

 DockerFile的指令

 FROM #基础镜镜像,一切从这里开始构建

 MAINTAINER #镜像是谁写的,姓名+邮箱

 RUN #镜像构建的时候需要运行的命令

 ADD #步骤: tomattomcat镜像,这个压缩包!添加内容

 WORKDIR #镜像的工作目录

VOLUME # 挂载的目录

 EXPOSE #保留端口配置

 CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代

 ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令

 ONBUILD #当构建一个被继承《DockerF1eoBuLp《这个时候就会运行ONBUILD的指令。触发指令。

 COPY #类似ADD,将我们文件拷贝到镜像中

 ENV #构建的时候设置环境变量!

 

创建一个自己的 centos

# 1编写 Dockerf ile的文件

vim dockfile-centos
FROM centos
MAINTAINER yys<534640040@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo SMYPATH
CMD echo "----end----"
CMD /bin/bash

#2、通过这个文件构建镜像

命令docker build -f dockerfile文件路径t 镜像名:[tag]

docker build -f dockfile-centos -t mycentos:0.1 .

#3、测试运行

docker run -it mycentos:0.1

进入后发现目录
[root@3e4869beca3d local]# pwd
/usr/local

4.docker网络

yys@yys:~/my$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo   # 本机回环地址
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether 00:0c:29:23:9e:b2 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 192.168.31.167/24 brd 192.168.31.255 scope global dynamic noprefixroute ens33  # 虚拟机ip
       valid_lft 34384sec preferred_lft 34384sec
    inet6 fe80::9735:da9c:896a:17c3/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:27:19:3a:23 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0  # docker0 地址
       valid_lft forever preferred_lft forever
    inet6 fe80::42:27ff:fe19:3a23/64 scope link 
       valid_lft forever preferred_lft forever

docker run -d -P --name tomcat01 tomcat

查看容器ip地址

docker exec -it tomcat01 ip addr

yys@yys:~/my$ docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0  # docker地址
       valid_lft forever preferred_lft forever
 

方法二:要查看容器的 IP 地址,你可以使用以下命令:

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_id_or_name>

替换 <container_id_or_name> 为你的容器的实际 ID 或名称。例如,在你的情况下,可以使用以下命令来查看 MySQL 容器的 IP 地址:

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-mysql-container

这将输出 MySQL 容器的 IP 地址。请注意,这个 IP 地址只在 Docker 内部网络中可用,如果你想要从主机或其他网络中访问容器,你可能需要使用容器的公共端口(在你的情况下是 3306)。

 

在容器外可以ping通 

ping 172.17.0.2

yys@yys:~/my$ ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 比特,来自 172.17.0.2: icmp_seq=1 ttl=64 时间=0.319 毫秒
64 比特,来自 172.17.0.2: icmp_seq=2 ttl=64 时间=0.093 毫秒
64 比特,来自 172.17.0.2: icmp_seq=3 ttl=64 时间=0.062 毫秒
64 比特,来自 172.17.0.2: icmp_seq=4 ttl=64 时间=0.102 毫秒
64 比特,来自 172.17.0.2: icmp_seq=5 ttl=64 时间=0.118 毫秒
64 比特,来自 172.17.0.2: icmp_seq=6 ttl=64 时间=0.098 毫秒
64 比特,来自 172.17.0.2: icmp_seq=7 ttl=64 时间=0.093 毫秒
64 比特,来自 172.17.0.2: icmp_seq=8 ttl=64 时间=0.099 毫秒
64 比特,来自 172.17.0.2: icmp_seq=9 ttl=64 时间=0.055 毫秒
^C
--- 172.17.0.2 ping 统计 ---
已发送 9 个包, 已接收 9 个包, 0% 包丢失, 耗时 8186 毫秒


原理

1、我们每启动一个 docker容器, dockerdock就会给容器分配一个ip,我们只要安装了 docker,就会有一个网卡 docker0

桥接模式,使用的技术是veth-pair技术!

再新建一个容器,查看ip

yys@yys:~/my$ docker run -d -P --name tomcat02 tomcat
yys@yys:~/my$ docker exec -it tomcat02 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0   # docker地址
       valid_lft forever preferred_lft forever
 

我们发现这个容器带来网卡,都是一对对的

veth-pair就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连

#正因为有这个特性,veth-pair充当一个桥梁,连接各种虚拟网络设备的

# Openstac, Docker容器之间的连接,S的连接,都是使用evth-pair技术

3、我们来测试下 tomcat1 tomcat02是否可以ping!

docker exec -it tomcat02 ping 172.17.0.2

 yys@yys:~/my$ docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.195 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.122 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.108 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.121 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.129 ms
64 bytes from 172.17.0.2: icmp_seq=6 ttl=64 time=0.054 ms
^C
--- 172.17.0.2 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 116ms
rtt min/avg/max/mdev = 0.054/0.121/0.195/0.042 ms

结论容器和容器之间是可以互相ping通的!

4.1 --link(不推荐)

思考一个场景,我们编写了一个微服务, database url=ip:,项目不重启,数据库p换掉了,我们希望可以处理这个问题,可以

名字来进行访问容器?

docker run -d -P --name tomcat03 --link tomcat02 tomcat

 

如果报错,删除镜像

docker: Error response from daemon: Conflict. The container name "/tomcat03" is already in use by container "9f1a724b270d50146922c5d34536fb307ec7f8685e2fd0df2cbd796cd8eaf846". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.

 tomcat03和tomcat02的位置不能颠倒

docker exec -it tomcat03 ping tomcat02

yys@yys:~$ docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.2): icmp_seq=1 ttl=64 time=0.452 ms
64 bytes from tomcat02 (172.17.0.2): icmp_seq=2 ttl=64 time=0.127 ms
64 bytes from tomcat02 (172.17.0.2): icmp_seq=3 ttl=64 time=0.302 ms
64 bytes from tomcat02 (172.17.0.2): icmp_seq=4 ttl=64 time=0.133 ms
^C
--- tomcat02 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 67ms
rtt min/avg/max/mdev = 0.127/0.253/0.452/0.135 ms
 

4.2 自定义网络

网络模式

 bridge:桥接 docker(默认,自己床架也使用 bridge模式)

none不配置网络

host:和宿主机共享网络

 container:容器网络连通!(用的少!局限很大)

  • bridge:多由于独立container之间的通信
  • host: 直接使用宿主机的网络,端口也使用宿主机的
  • overlay:当有多个docker主机时,跨主机的container通信
  • macvlan:每个container都有一个虚拟的MAC地址
  • none: 禁用网络

测试

我们直接启动的命令--net bridge,而这个就是我们的 dockero

 docker run -d - --name tomcat01 tomcat

 docker run-d -p --name tomcato1 --net bridge tomcat

 dockero特点,默认,域名不能访问,link可以打通连接

删除一个network命令

docker network rm net名字

docker network rm mynet

创建 桥接(注意此时虚拟机桥接的话会没网,改成NAT模式可以)

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.31.1 mynet
docker network ls

yys@yys:~$ docker network ls

NETWORK ID     NAME      DRIVER    SCOPE

7c624fac99e1   bridge    bridge    local

175f9426229c   host      host      local

54b88a6b2682   mynet     bridge    local

da54539df3f5   none      null      local

docker network inspect mynet

yys@yys:~$ docker network inspect mynet 
[
    {
        "Name": "mynet",
        "Id": "54b88a6b2682eb016a4ddcf84ae96ff6552a81ab14f252f307e40ed86c44d162",
        "Created": "2021-04-03T16:11:32.788070366+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.31.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
 

根据mynet 启动两个容器

docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat


可以ping通

根据ip

docker exec -it tomcat-net-01 ping 192.168.0.2

根据名字 

docker exec -it tomcat-net-01 ping tomcat-net-02

4.3 网络联通

新建一个容器

docker run -d -P --name tomcate01 tomcat

与 tomcate01 联通

docker network connect mynet tomcate01

然后可以ping通了

docker exec -it tomcat-net-01 ping tomcate01

4.4 Redis集群部署实战

docker network create redis --subnet 172.38.0.0/16

使用命令创建

进入root用户

sudo su

创建6个redis  

for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379 
bind 0.0.0.0
cluster-enabled yes 
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

启动6个redis 

docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
    -v /mydata/redis/node-1/data:/data \
    -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf


docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
-v /mydata/redis/node-3/data:/data \
-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
-v /mydata/redis/node-4/data:/data \
-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

启动redis

docker exec -it redis-1 /bin/sh

再/date下创建集群

redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

选yes 

yys@yys:~$ docker exec -it redis-1 /bin/sh
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --clu
ster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: 8103a7f2b0adc4614f1ce8f7f5c50602079e1d8a 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: 136143e1f9f8c92e566654b6160594b5dc88f81e 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 886909d77ab976bfb48aa59df28b41ba9b820e1f 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: f984d685a87a3f3eb6b69f50174473f4738e82cf 172.38.0.14:6379
   replicates 886909d77ab976bfb48aa59df28b41ba9b820e1f
S: f96586cdf63b80ffacb579d87d170c7ce30916ac 172.38.0.15:6379
   replicates 8103a7f2b0adc4614f1ce8f7f5c50602079e1d8a
S: c39b1db912e65ecfdc24695c95886de1a5de3a29 172.38.0.16:6379
   replicates 136143e1f9f8c92e566654b6160594b5dc88f81e
Can I set the above configuration? (type 'yes' to accept): yes

redis-cli -c

/data # redis-cli -c

CLUSTER INFO


127.0.0.1:6379> CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:324
cluster_stats_messages_pong_sent:344
cluster_stats_messages_sent:668
cluster_stats_messages_ping_received:339
cluster_stats_messages_pong_received:324
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:668
127.0.0.1:6379> 

 

5.安装乌班图

 

1、拉取一个 ubuntu 的镜像

执行如下命令拉取一个 ubuntu 的最新镜像

docker pull ubuntu

示例:

$ docker pull ubuntu 
Using default tag: latest 
...
注:摘取镜像的完整命令是 docker pull image:tag,如果 :tag 没传,则会自动设置为 latest,即可上面的命令相当于

docker pull ubuntu:latest
2、查看镜像

执行如下命令查看本地已拉取的镜像

docker images


示例:

$ docker images                 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE 
ubuntu              latest              72300a873c2c        2 months ago        64.2MB
可以看到,我们拉取一个干净的 ubuntu 镜像的大小只有 64 MB,比起使用 ISO 镜像文件安装虚拟机的动辙数 GB 大小,它显示是太小巧太方便了,而且拉取也非常快(可以设置国内镜像源来加速使拉取速度更快)。 

3、运行一个基于 Ubuntu 的 Linux 容器

执行如下命令可以运行一个 Ubuntu 的容器。

docker run --name ubuntu_demo -itd ubuntu


示例:

$ docker run --name ubuntu_demo -itd ubuntu     
049131a972403a309ffebe5b63243066b3d0a497e399ee0dc91cba6924f6f40b
其中:

–name ubuntu_demo 表示给运行的窗口取名为 ubuntu_demo

-i 表示 interactive 可交互的,变即可以从标准输入与容器交互。

-t 表示给容器分配一个虚拟终端。

-d 这个参数表示的是在后台运行,即 –deamon。

ubuntu 表示的是运行容器所使用的镜像名称。

4、查看运行容器

docker ps -a | grep ubuntu_demo

$ docker ps -a | grep ubuntu_demo
049131a97240     ubuntu              "/bin/bash"              3 minutes ago       Up 3 minutes         ubuntu_demo
可以看到,后台已经运行了一个叫做 ubuntu_demo 的窗口,容器 ID 的前 12 位部分是 049131a97240

总结

进入  Ubuntu Linux 容器内部

如果要进入该容器内部,则可以使用下面的命令:

docker exec -it ubuntu_demo /bin/bash

$ docker exec -it ubuntu_demo /bin/bash
其中ubuntu_demo 是 docker 容器的 名称,也可以使用容器名称,如:

docker exec -it 0491 /bin/bash
注:

(1) 容器 ID 0491 可以写尽量少的位数,只要不与其他的 container id 重复即可。

(2) 其中 docker exec 是固定命令,-it 是 interactive 和 tty 缩写,后面跟容器 id 或名称,/bin/bash 表示内部使用的 shell 方式,也可以简写 bash。

附录

一些小 tips:由于是完全干净的 Ubuntu 系统,所以系统中的很多的工具或者组件是没有的,需要自行安装,不过使用 apt-get 工具也非常地方便。

下面列几个常用的

在国内使用 apt-get,最重要的就是设置国内 apt 镜像源,可以请参考另一篇文章:【原创】Ubuntu apt 更改国内阿里源

 

  更新 apt-get 工具,这个步骤优先级最高,因为不更新很多组件安装不了

apt-get update

安装 vim 工具,初始系统中连 vi 都没有,显然很需要。另外,可以使用 apt-get 命令简写 apt 来执行安装,效果相同。  

apt install vim

换源

换源

安装python3

apt install python3

安装pip3

apt install python3-pip

 

 

安装 wget 工具,如果你需要从网络上下载资源 

apt install wget 

安装 curl 工具,如果你需要使用 curl 来访问网络资源

apt install curl


如果你需要使用网络工具,比如 ifconfig 等,安装 net-tools

apt install net-tools

  如果需要使用 ping命令

apt install iputils-ping


  如果需要使用 telnet,安装 telnet

apt install telnet

6.重新启动一个已经存在的 Docker 容器

要重新启动一个已经存在的 Docker 容器,你可以使用 docker start 命令,然后指定容器的名称或容器的唯一标识符(容器ID)。

以下是如何重新启动一个已经存在的容器的步骤:

  1. 获取容器的名称或容器ID:

    使用 docker ps -a 命令来列出所有容器(包括已停止的容器),并找到你想要重新启动的容器的名称或ID。

    docker ps -a

    这将列出容器的信息,包括容器ID、名称、状态等。

  2. 使用 docker start 命令重新启动容器:

    使用以下命令来重新启动容器,其中 container_name 替换为容器的名称或 container_id 替换为容器的唯一标识符(容器ID):

    docker start container_name

    docker start container_id

    例如,如果你的容器名称是 "my-ubuntu-container",则可以使用以下命令重新启动它:

    docker start my-ubuntu-container

    如果容器成功重新启动,你可以使用 docker attach 命令来附加到容器的终端:

    docker attach my-ubuntu-container

    你将能够访问容器内的交互式终端,就像你刚刚启动的容器一样。

 

7.连接外部网络(外部adb)

要设置 Docker 容器的网络配置,你可以选择使用默认桥接网络或创建自定义网络,具体方法如下:

1. 使用默认桥接网络:
Docker 默认情况下将容器连接到桥接网络,这使容器可以与主机和其他容器通信。你无需额外配置,容器会自动连接到默认桥接网络。

2. 创建自定义桥接网络:
如果需要创建自己的网络,可以执行以下命令:

docker network create my-bridge-network

这将建立一个自定义网络,允许容器与主机上的服务和外部设备通信。请注意,这可能存在安全风险,因为容器可以直接访问主机上的服务。

你的选择取决于需求。绝大多数情况下,使用默认的桥接网络就足够了,只有在特定情况下才需要自定义网络或连接到主机网络。根据需求选择适当的网络配置,以确保容器能够访问外部网络或其他容器。

如果你需要将容器连接到自定义网络 'my-bridge-network':

首先,重新启动容器:

docker start my-ubuntu-container

这将启动之前停止的容器,但容器仍然连接到之前的网络,网络配置不会改变。

接着,连接容器到自定义网络 'my-bridge-network':

docker network connect my-bridge-network my-ubuntu-container

这将使容器同时连接到默认的桥接网络和 'my-bridge-network',容器可以在这两个网络中通信。

如果你只想将容器连接到 'my-bridge-network' 而不再连接到默认的桥接网络,可以先断开容器与默认网络的连接,然后再连接到 'my-bridge-network':

首先断开容器与默认网络的连接:

docker network disconnect bridge my-ubuntu-container

然后,再连接到 'my-bridge-network'。

现在,你的容器应该同时连接到 'my-bridge-network' 和默认的桥接网络,你可以根据需要访问这两个网络。

8.以root用户启动容器,方便装软件

参考Jenkins

9.用docker-compose ,建立一个乌班图容器和mysql容器 ,连接外部网络,以root用户运行,在容器访问mysql容器

在 Windows 上使用 Docker Compose 来建立一个包含 Ubuntu 和 MySQL 容器的应用程序,并连接到外部网络,可以按照以下步骤进行:

  1. 安装 Docker 和 Docker Compose:

  2. 创建 Docker Compose 文件:
    创建一个名为 docker-compose.yml 的文件,定义您的应用程序。以下是一个简单的示例:

    version: '3'
    
    services:
      ubuntu:
        image: ubuntu
        command: tail -f /dev/null
        container_name: my-ubuntu-container
        network_mode: "bridge"
        user: "root"
    
      mysql:
        image: mysql:latest
        container_name: my-mysql-container
        environment:
          MYSQL_ROOT_PASSWORD: your_root_password
        ports:
          - "3306:3306"
        network_mode: "bridge"

    在上面的示例中,我们定义了两个服务,一个是 Ubuntu 容器,另一个是 MySQL 容器。network_mode: "bridge" 允许容器连接到默认的 Docker 桥接网络。user: "root" 用于在 Ubuntu 容器中以 root 用户身份运行。

    请替换 your_root_password 为您想要设置的 MySQL root 用户密码。

在 Docker Compose 中,network_mode 用于指定容器使用的网络模式。网络模式决定了容器与主机和其他容器之间的网络连接方式。以下是一些常见的 network_mode 模式:

  1. bridge:

    network_mode: "bridge"

    默认网络模式。容器使用 Docker 守护进程的桥接网络。每个容器都有自己的网络命名空间,并分配一个唯一的 IP 地址。这是最常用的模式。

  2. host:

    network_mode: "host"

    容器与主机共享网络命名空间。容器使用主机的网络堆栈,与主机具有相同的网络接口和 IP 地址。这使得容器可以轻松地与主机上的服务通信,可以ipv6。

  3. none:

    network_mode: "none"

    容器不使用网络命名空间。这意味着容器中没有网络接口、IP 地址或默认路由。容器之间和容器与主机之间无法直接通信。

  4. container:

    network_mode: "container:container_name_or_id"

    容器与另一个指定容器共享网络命名空间。这意味着两个容器使用相同的网络接口和 IP 地址。它们可以直接通信,就像在同一主机上一样。

  5. 自定义网络(user-defined networks):
    你还可以在 Docker Compose 中创建自定义的用户定义网络,并将容器连接到这些网络。这通常使用 networks 部分进行配置。

networks:
  my_network:
    driver: bridge

services:
  my_service:
    image: my_image
    networks:
      - my_network

在这个例子中,my_service 容器将连接到名为 my_network 的自定义网络。

选择适当的网络模式取决于你的应用程序和部署需求。默认情况下,大多数容器都可以使用 bridge 模式,并通过端口映射进行需要的网络连接。

  1. 一直运行代码

要确保 Docker 容器在宿主机启动时自动运行,你可以使用 Docker Compose 的 restart 配置。在你的 docker-compose.yml 文件中,你可以添加 restart: always 来指定容器在宿主机启动时始终重新启动。以下是修改后的 docker-compose.yml 文件示例:

要让 Ubuntu 容器访问本地文件夹,你可以使用 Docker Compose 的 volumes 配置。这允许你将宿主机上的文件夹映射到容器中,使容器能够访问宿主机文件系统中的文件。

假设你想让 Ubuntu 容器访问宿主机上的 /path/to/local/folder 文件夹,/container/path是容器内挂载的目标路径。这样,您就可以在容器中访问宿主机上的文件了:

version: '3'
   
services:
  ubuntu:
    image: ubuntu
    command: tail -f /dev/null
    container_name: my-ubuntu-container
    network_mode: "bridge"
    user: "root"
    restart: always  # 添加此行配置
    volumes:
          - /path/to/local/folder:/container/path # 将本地文件夹映射到容器中/container/path目录,windows也这样
  mysql:
    image: mysql:latest
    container_name: my-mysql-container
    environment:
      MYSQL_ROOT_PASSWORD: your_root_password
    ports:
      - "3306:3306"
    network_mode: "bridge"
    restart: always  # 添加此行配置

在上述配置中,我们为 ubuntu 和 mysql 服务添加了 restart: always 配置。这将确保这两个容器在宿主机启动时始终重新启动。

完成修改后,保存文件并重新启动你的 Docker 容器:

docker-compose down
docker-compose up -d

这样,你的 Ubuntu 和 MySQL 容器就会在宿主机启动时自动运行。

 

  1. 启动应用程序:
    打开命令行工具,导航到包含 docker-compose.yml 文件的目录,然后运行以下命令:

    docker-compose up -d

    这将启动 Ubuntu 和 MySQL 容器,并在后台运行。

  2. 连接到 MySQL 容器:
    使用 MySQL 客户端或其他工具连接到 MySQL 容器。您可以使用以下参数:

    示例命令行连接 MySQL 容器:

    mysql -h localhost -P 3306 -u root -p

    输入您在 docker-compose.yml 中设置的密码,即可连接到 MySQL 服务器。

    • 主机: localhost 或者宿主机的 IP 地址。
    • 端口: 3306(我们在 docker-compose.yml 中映射的端口)。
    • 用户名: root
    • 密码: 之前在 docker-compose.yml 中设置的密码。
  3. 停止和清理:
    当您完成测试后,可以使用以下命令停止和删除容器:

    docker-compose down

    这会停止并删除运行的容器,但不会删除数据卷。如果需要删除数据卷,请使用 docker-compose down -v 命令。

请注意,上述示例仅用于演示目的,实际部署时,您可能需要添加更多的配置,例如数据卷、持久性存储、安全性设置等。

用 ubuntu容器访问mysql容器

要从 Ubuntu 容器中访问 MySQL 容器,你需要确保它们位于同一网络中,并且 MySQL 服务已经启动并监听正确的端口。在你的 docker-compose.yml 文件中,我们使用了默认的 Docker 桥接网络,因此两个容器应该能够相互通信。

以下是步骤:

  1. 确保 MySQL 服务已启动:
    在 docker-compose.yml 文件中,你定义了一个名为 my-mysql-container 的 MySQL 容器。确保该容器已经启动并且 MySQL 服务正在运行。如果你遇到问题,可以检查容器的日志以获取更多信息。

  2. 进入 Ubuntu 容器:
    使用 docker exec 进入 Ubuntu 容器的命令,如之前所述:

    docker exec -it my-ubuntu-container /bin/bash
  3. 安装 MySQL 客户端:
    在 Ubuntu 容器内,你可能需要安装 MySQL 客户端工具。运行以下命令:

    apt-get update
    apt-get install mysql-client
  4. 连接到 MySQL 容器:
    现在,你可以使用 MySQL 客户端连接到 MySQL 容器。请记住使用 MySQL 容器的 IP 地址(可以使用 docker inspect my-mysql-container 查看),以及在 docker-compose.yml 文件中定义的端口。

    mysql -h <MySQL_Container_IP> -P <MySQL_Container_Port> -u root -p

    替换 <MySQL_Container_IP> 和 <MySQL_Container_Port> 为实际的 MySQL 容器的 IP 地址和端口。然后输入密码,即可连接到 MySQL 服务器。

请注意,由于默认 Docker 桥接网络,你可以使用 MySQL 容器的名称作为主机名。例如,如果你的 MySQL 容器的名称为 my-mysql-container,则连接命令可以简化为:

mysql -h my-mysql-container -u root -p

以上步骤应该让你在 Ubuntu 容器内通过 MySQL 客户端与 MySQL 容器建立连接。确保在实际环境中使用实际的容器名称、IP 地址和端口。

 

10.备份和恢复

备份和恢复 Docker 容器可以通过几种不同的方法来实现。以下是其中两种常见的方法:

备份容器:

  1. 首先,停止正在运行的容器:

    docker stop <容器名称或ID>
  2. 使用 docker export 命令将容器导出为一个 tar 文件:

    docker export -o /path/to/backup/container_backup.tar <容器名称或ID>

恢复容器:

docker import 命令用于从归档文件(通常是 tar 文件)中导入镜像,并且不能直接为镜像添加标签。但你可以使用 docker tag 命令在导入后为镜像添加标签。

以下是如何在导入镜像后为其添加标签的步骤:

  1. 首先使用 docker import 命令导入镜像(如果不带标签默认latest,如ubuntu:22.04):

    docker import /path/to/backup/container_backup.tar <新镜像名>:<tag标签>

这将为导入的镜像 my_image 添加了标签 tag1

注:如果用docker-compose,运行docker-compose -d up 就可以启动了。镜像的名字和tag要都匹配

11.有互联网连接的情况下离线安装 Docker 镜像或者某台电脑有代理情况

要在没有互联网连接的情况下离线安装 Docker 镜像,你可以使用以下步骤:

  1. 在有互联网连接的机器上下载镜像:
    首先,你需要在一台有互联网连接的机器上下载所需的 Docker 镜像。可以使用以下命令拉取特定版本的 jellyfin/jellyfin 镜像:

    docker pull jellyfin/jellyfin:2024070805

    这将从 Docker Hub 下载 jellyfin/jellyfin 版本为 2024070805 的镜像到当前机器。

  2. 保存镜像到文件:
    下载完成后,可以使用 docker save 命令将镜像保存为 tar 归档文件:

    docker save -o jellyfin-jellyfin-2024070805.tar jellyfin/jellyfin:2024070805

    这将生成一个名为 jellyfin-jellyfin-2024070805.tar 的文件,其中包含了 jellyfin/jellyfin:2024070805 镜像的所有层和元数据。

  3. 将镜像文件传输到离线机器:
    将生成的 jellyfin-jellyfin-2024070805.tar 文件通过安全的方式传输到没有互联网连接的目标机器,可以使用 USB 驱动器、网络共享或其他便携式存储设备。

  4. 在离线机器上加载镜像:
    在离线机器上,可以使用 docker load 命令加载从在线机器上导出的镜像文件:

    docker load -i jellyfin-jellyfin-2024070805.tar

    这将在离线机器上加载并注册 jellyfin/jellyfin:2024070805 镜像。

通过这些步骤,你就可以在没有互联网连接的环境中安装和使用特定版本的 jellyfin/jellyfin Docker 镜像。


扩展1: sh 脚本保存所有镜像到指定目录

你可以使用一个简单的 sh 脚本来实现自动保存所有 Docker 镜像到指定目录。这个脚本将获取所有本地镜像的名称和标签,然后使用 docker save 命令保存它们。

下面是一个示例 sh 脚本:

#!/bin/bash

# 指定保存镜像的目录
SAVE_DIR="/path/to/save/images"  # 修改为你想要保存的路径

# 如果保存目录不存在,则创建该目录
if [ ! -d "$SAVE_DIR" ]; then
  mkdir -p "$SAVE_DIR"
fi

# 获取所有本地镜像的名称和标签
IMAGES=$(docker images --format "{{.Repository}}:{{.Tag}}")

# 遍历每个镜像,并将其保存到指定目录
for IMAGE in $IMAGES; do
  # 提取镜像名称和标签
  IMAGE_NAME=$(echo "$IMAGE" | cut -d':' -f1)
  IMAGE_TAG=$(echo "$IMAGE" | cut -d':' -f2)
  
  # 将 / 替换为 - 以创建文件名
  OUTPUT_FILE="$SAVE_DIR/${IMAGE_NAME//\//-}-$IMAGE_TAG.tar"
  
  # 保存镜像
  echo "Saving $IMAGE to $OUTPUT_FILE"
  docker save -o "$OUTPUT_FILE" "$IMAGE"
done

说明:

  1. SAVE_DIR 是指定镜像保存的目录路径,需要根据你的需求进行修改。
  2. docker images --format "{{.Repository}}:{{.Tag}}" 获取本地镜像的名称和标签,格式为 repository:tag
  3. for 循环遍历所有镜像,并使用 docker save 将每个镜像保存到指定目录,文件名将 / 替换为 -,以避免文件名中的非法字符。

使用方法:

  1. 将上述代码保存为一个 .sh 文件(例如 save_images.sh)。
  2. 确保脚本有执行权限:chmod +x save_images.sh
  3. 运行脚本:./save_images.sh

扩展2: sh 脚本自动加载(load)当前目录下所有以 .tar 结尾的 Docker 镜像文件

可以编写一个简单的 sh 脚本来自动加载当前目录下所有以 .tar 结尾的 Docker 镜像文件。脚本会遍历当前目录,找到所有 .tar 文件,并依次使用 docker load 命令加载这些镜像。

下面是一个示例 sh 脚本:

#!/bin/bash

# 获取当前目录下所有 .tar 文件
for tar_file in *.tar; do
  # 检查是否有匹配的 .tar 文件
  if [ -e "$tar_file" ]; then
    echo "Loading Docker image from $tar_file"
    docker load -i "$tar_file"
  else
    echo "No .tar files found in the current directory."
  fi
done

说明:

  1. for tar_file in *.tar; do:遍历当前目录下所有 .tar 文件。
  2. docker load -i "$tar_file":使用 docker load 命令加载每个 .tar 文件。
  3. if [ -e "$tar_file" ]; then:检查是否有 .tar 文件存在,如果存在,则进行加载;如果没有 .tar 文件,输出提示信息。

使用方法:

  1. 将脚本保存为 load_images.sh
  2. 给脚本执行权限:chmod +x load_images.sh
  3. 运行脚本:./load_images.sh

这个脚本会自动加载当前目录下的所有 .tar Docker 镜像文件。

 


12.添加外网代理

从 docker info 输出可以看到你的 Docker 客户端和服务器正常运行,且没有显示出与代理相关的问题。你现在需要通过配置代理来使 Docker 通过 Clash 连接外网。你已经成功验证了 Docker 服务运行正常。

代理配置确认(若路径不存在,自行创建)

  1. 确保你已经正确配置代理:

    • 代理设置需要添加到 Docker 配置文件 ~/.docker/config.json 中。
    • 如果文件不存在,可以创建它并配置。
  2. 检查 ~/.docker/config.json 的代理设置:

    编辑 ~/.docker/config.json

    sudo vim ~/.docker/config.json

    并添加如下内容(确保代理地址和端口符合你本地的设置):

    {
      "proxies": {
        "default": {
          "httpProxy": "http://127.0.0.1:7890",
          "httpsProxy": "http://127.0.0.1:7890",
          "noProxy": "localhost,127.0.0.1,::1"
        }
      }
    }
  3. 确保 Docker 服务的代理设置:

    如果你需要设置 Docker Daemon 的代理(例如,拉取镜像等操作),可以通过以下步骤配置:

    编辑 /etc/systemd/system/docker.service.d/override.conf 文件(如果不存在可以手动创建):

    sudo nano /etc/systemd/system/docker.service.d/override.conf

    在文件中添加代理环境变量:

    [Service]
    Environment="HTTP_PROXY=http://127.0.0.1:7890"
    Environment="HTTPS_PROXY=http://127.0.0.1:7890"
    Environment="NO_PROXY=localhost,127.0.0.1"

    然后重新加载并重启 Docker 服务:

    sudo systemctl daemon-reload
    sudo systemctl restart docker

测试代理配置

可以通过以下命令来确认 Docker 是否能够通过代理连接:

docker pull hello-world

如果成功拉取镜像,说明代理配置正确。如果遇到问题,请提供错误信息,我可以继续帮助你排查。

 

13.非host模式加入ipv6

  jenkins:
    image: jenkins/jenkins:2.469-jdk17
    container_name: jenkins
    user: "root"
    network_mode: "bridge"
    ports:
      - 8080:8080
      - 4000:4000
      - 17310:17310
    volumes:
      - /mnt/nas/share/:/mnt/nas/share
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
      - /home/yys:/home/yys
    environment:
      - LANG=C.UTF-8
      - JAVA_OPTS=-Dfile.encoding=UTF-8 -Djava.awt.headless=true
    restart: always

好的,你提供了一个 docker-compose (虽然看起来像只是 services 部分) 中 jenkins 服务的配置。 我们来分析一下这个配置,并找出可能与之前你提到的 Git 连接问题相关的地方,同时给出建议。

配置分析:

  • jenkins:: 定义了名为 jenkins 的服务。

  • image: jenkins/jenkins:2.469-jdk17: 使用官方 jenkins/jenkins 镜像,版本为 2.469-jdk17。

  • container_name: jenkins: 将容器命名为 jenkins。

  • user: "root": 以 root 用户身份运行容器。 (不推荐,除非必须)

  • network_mode: "bridge": 使用默认的桥接网络模式。

  • ports:: 端口映射:

    • 8080:8080: 将容器的 8080 端口映射到宿主机的 8080 端口。

    • 4000:4000: 将容器的 4000 端口映射到宿主机的 4000 端口。

    • 17310:17310:将容器的 17310端口映射到宿主机的 17310端口。

  • volumes:: 挂载卷:

    • /mnt/nas/share/:/mnt/nas/share: 挂载宿主机的 /mnt/nas/share/ 目录到容器的 /mnt/nas/share 目录。

    • /etc/timezone:/etc/timezone:ro: 挂载宿主机的 /etc/timezone 文件到容器的 /etc/timezone 文件 (只读)。

    • /etc/localtime:/etc/localtime:ro: 挂载宿主机的 /etc/localtime 文件到容器的 /etc/localtime 文件 (只读)。

    • /home/yys:/home/yys: 挂载宿主机的 /home/yys 目录到容器的 /home/yys 目录。

  • environment:: 设置环境变量:

    • LANG=C.UTF-8: 设置字符编码。

    • JAVA_OPTS=-Dfile.encoding=UTF-8 -Djava.awt.headless=true: 设置 JVM 参数,确保字符编码和 headless 模式。

  • restart: always: 容器总是尝试重启。

与 Git 连接问题的关联:

  1. 网络模式 network_mode: "bridge":

    • 你使用了默认的 bridge 网络模式。如之前讨论的,这种模式可能对 IPv6 支持不够友好,导致容器无法连接到 mnas.yys.zone 的 IPv6 地址。

    • 改进建议:

      • 尝试自定义桥接网络,并启用 IPv6: 如前所述,你可以定义一个自定义的桥接网络,并且启用 IPv6,让容器加入这个网络。

  2. 缺少 DNS 配置:

    • 这个配置中没有指定 DNS 服务器。容器可能会使用默认的 DNS 设置,这可能无法正确解析 mnas.yys.zone 的 IPv6 地址。

    • 改进建议:

      • 指定 DNS 服务器: 使用 dns 选项,指定 Google 的公共 DNS 服务器, 例如 8.8.8.8 和 2001:4860:4860::8888。

  3. root 用户权限:

    • 虽然 user: "root" 可以解决一些权限问题,但它会降低容器的安全性。你应该尽可能避免在容器中使用 root 用户。

    • 改进建议:

      • 不使用root用户: 可以考虑使用 Jenkins 镜像中默认的 jenkins 用户,如果你需要访问 /home/yys 下的文件,可以修改挂载目录的权限或者修改Jenkins用户拥有/home/yys目录下的文件访问权限。

  4. 端口冲突:

  • 你映射了多个端口:8080, 4000, 17310.你需要确认宿主机上这些端口没有被其他服务占用。

docker-compose.yml 文件的修改建议:

以下是一个修改后的 docker-compose.yml 文件的示例,它解决了上述问题并进行了一些改进:

version: "3.9"
services:
  jenkins:
    image: jenkins/jenkins:2.469-jdk17
    container_name: jenkins
    # user: "root"   # 建议使用默认的 jenkins 用户, 或者根据需要配置其他用户
    networks:
      - my-ipv6-network  # 将容器加入自定义 IPv6 网络
    ports:
      - 8080:8080
      - 4000:4000
      - 17310:17310
    volumes:
      - /mnt/nas/share/:/mnt/nas/share
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
      - /home/yys:/home/yys  # 可以考虑给容器内部的 Jenkins 用户赋予 /home/yys 目录的访问权限
    environment:
      - LANG=C.UTF-8
      - JAVA_OPTS=-Dfile.encoding=UTF-8 -Djava.awt.headless=true
    restart: always
    dns:  # 指定 DNS 服务器
      - "8.8.8.8"
      - "2001:4860:4860::8888"
networks:
  my-ipv6-network: # 定义一个自定义 IPv6 网络
    driver: bridge
    ipam:
      config:
        - subnet: fd00::/64
    enable_ipv6: true

修改步骤:

  1. 将上面的内容保存到 docker-compose.yml 文件中(或者覆盖你的旧文件)。

  2. 重新启动你的 docker-compose 项目:

    docker-compose down
    docker-compose up -d

如果修改后仍然存在问题:

  1. 宿主机网络配置: 确保宿主机正确配置了 IPv6,并且可以访问 mnas.yys.zone 。

  2. 检查 Jenkins 日志: 查看 Jenkins 容器的日志,查找是否有关于 Git 连接问题的错误信息。

      docker logs jenkins
    
  1. 检查 端口占用: 检查宿主机端口是否被占用。

通过以上的修改和排查,应该能够解决你 Jenkins 容器 Git 连接的问题。 如果问题仍然存在,请提供更多的信息,我将尽力帮助你。