docker基础
地址:https://docs.docker.com/engine/install/ubuntu/
最新教程: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 服务,您可以尝试以下方法之一:
-
使用
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.
下载安装
阿里云提供的下载地址: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:
-
更新系统:
在安装Docker之前,请确保您的树莓派系统是最新的。打开终端并运行以下命令:
sudo apt update sudo apt upgrade
-
安装依赖项:
安装Docker所需的一些依赖项。运行以下命令:
sudo apt install -y apt-transport-https ca-certificates software-properties-common
-
添加Docker的官方GPG密钥:
运行以下命令以添加Docker官方的GPG密钥:
curl -fsSL https://download.docker.com/linux/raspbian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
-
添加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
。 -
更新APT包列表:
运行以下命令以更新APT包列表:
sudo apt update
-
安装Docker:
安装Docker引擎。运行以下命令:
sudo apt install -y docker-ce docker-ce-cli containerd.io
-
启用Docker服务:
启动并启用Docker服务,以便它在系统启动时自动运行:
sudo systemctl enable docker sudo systemctl start docker
-
验证安装:
运行以下命令来验证Docker是否正确安装:
sudo docker --version
如果成功安装,它将显示Docker的版本信息。
现在,您已经在树莓派上成功安装了Docker。您可以使用Docker来运行容器化的应用程序和服务。请注意,您需要在树莓派上使用sudo权限来运行Docker命令,或将用户添加到docker用户组以允许无需sudo权限来运行Docker命令。
在中国,你可以参考以下中文教程来在 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
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/
网址: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
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)
这里的普通用户是huali,组docker在安装docker的时候,就已经添加了,所以只需要执行两个操作即可:
sudo gpasswd -a $USER docker
newgrp docker
下载一个容器
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时,将容器暂停。
方式一:直接使用命令来挂载-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通的!
思考一个场景,我们编写了一个微服务, 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
网络模式
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
新建一个容器
docker run -d -P --name tomcate01 tomcat
与 tomcate01 联通
docker network connect mynet tomcate01
然后可以ping通了
docker exec -it tomcat-net-01 ping tomcate01
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>
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
要重新启动一个已经存在的 Docker 容器,你可以使用 docker start
命令,然后指定容器的名称或容器的唯一标识符(容器ID)。
以下是如何重新启动一个已经存在的容器的步骤:
-
获取容器的名称或容器ID:
使用
docker ps -a
命令来列出所有容器(包括已停止的容器),并找到你想要重新启动的容器的名称或ID。docker ps -a
这将列出容器的信息,包括容器ID、名称、状态等。
-
使用
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
你将能够访问容器内的交互式终端,就像你刚刚启动的容器一样。
要设置 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' 和默认的桥接网络,你可以根据需要访问这两个网络。
9.用docker-compose ,建立一个乌班图容器和mysql容器 ,连接外部网络,以root用户运行,在容器访问mysql容器
在 Windows 上使用 Docker Compose 来建立一个包含 Ubuntu 和 MySQL 容器的应用程序,并连接到外部网络,可以按照以下步骤进行:
-
安装 Docker 和 Docker Compose:
- 安装 Docker Desktop:https://www.docker.com/products/docker-desktop
- 安装 Docker Compose:https://docs.docker.com/compose/install/
-
创建 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
模式:
-
bridge:
network_mode: "bridge"
默认网络模式。容器使用 Docker 守护进程的桥接网络。每个容器都有自己的网络命名空间,并分配一个唯一的 IP 地址。这是最常用的模式。
-
host:
network_mode: "host"
容器与主机共享网络命名空间。容器使用主机的网络堆栈,与主机具有相同的网络接口和 IP 地址。这使得容器可以轻松地与主机上的服务通信,可以ipv6。
-
none:
network_mode: "none"
容器不使用网络命名空间。这意味着容器中没有网络接口、IP 地址或默认路由。容器之间和容器与主机之间无法直接通信。
-
container:
network_mode: "container:container_name_or_id"
容器与另一个指定容器共享网络命名空间。这意味着两个容器使用相同的网络接口和 IP 地址。它们可以直接通信,就像在同一主机上一样。
-
自定义网络(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
模式,并通过端口映射进行需要的网络连接。
-
一直运行代码
要确保 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 容器就会在宿主机启动时自动运行。
-
启动应用程序:
打开命令行工具,导航到包含docker-compose.yml
文件的目录,然后运行以下命令:docker-compose up -d
这将启动 Ubuntu 和 MySQL 容器,并在后台运行。
-
连接到 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
中设置的密码。
- 主机:
-
停止和清理:
当您完成测试后,可以使用以下命令停止和删除容器:docker-compose down
这会停止并删除运行的容器,但不会删除数据卷。如果需要删除数据卷,请使用
docker-compose down -v
命令。
请注意,上述示例仅用于演示目的,实际部署时,您可能需要添加更多的配置,例如数据卷、持久性存储、安全性设置等。
用 ubuntu容器访问mysql容器
要从 Ubuntu 容器中访问 MySQL 容器,你需要确保它们位于同一网络中,并且 MySQL 服务已经启动并监听正确的端口。在你的 docker-compose.yml
文件中,我们使用了默认的 Docker 桥接网络,因此两个容器应该能够相互通信。
以下是步骤:
-
确保 MySQL 服务已启动:
在docker-compose.yml
文件中,你定义了一个名为my-mysql-container
的 MySQL 容器。确保该容器已经启动并且 MySQL 服务正在运行。如果你遇到问题,可以检查容器的日志以获取更多信息。 -
进入 Ubuntu 容器:
使用docker exec
进入 Ubuntu 容器的命令,如之前所述:docker exec -it my-ubuntu-container /bin/bash
-
安装 MySQL 客户端:
在 Ubuntu 容器内,你可能需要安装 MySQL 客户端工具。运行以下命令:apt-get update apt-get install mysql-client
-
连接到 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 地址和端口。
备份和恢复 Docker 容器可以通过几种不同的方法来实现。以下是其中两种常见的方法:
备份容器:
-
首先,停止正在运行的容器:
docker stop <容器名称或ID>
-
使用
docker export
命令将容器导出为一个 tar 文件:docker export -o /path/to/backup/container_backup.tar <容器名称或ID>
恢复容器:
docker import
命令用于从归档文件(通常是 tar 文件)中导入镜像,并且不能直接为镜像添加标签。但你可以使用 docker tag
命令在导入后为镜像添加标签。
以下是如何在导入镜像后为其添加标签的步骤:
-
首先使用
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 镜像,你可以使用以下步骤:
-
在有互联网连接的机器上下载镜像:
首先,你需要在一台有互联网连接的机器上下载所需的 Docker 镜像。可以使用以下命令拉取特定版本的jellyfin/jellyfin
镜像:docker pull jellyfin/jellyfin:2024070805
这将从 Docker Hub 下载
jellyfin/jellyfin
版本为2024070805
的镜像到当前机器。 -
保存镜像到文件:
下载完成后,可以使用docker save
命令将镜像保存为 tar 归档文件:docker save -o jellyfin-jellyfin-2024070805.tar jellyfin/jellyfin:2024070805
这将生成一个名为
jellyfin-jellyfin-2024070805.tar
的文件,其中包含了jellyfin/jellyfin:2024070805
镜像的所有层和元数据。 -
将镜像文件传输到离线机器:
将生成的jellyfin-jellyfin-2024070805.tar
文件通过安全的方式传输到没有互联网连接的目标机器,可以使用 USB 驱动器、网络共享或其他便携式存储设备。 -
在离线机器上加载镜像:
在离线机器上,可以使用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
说明:
SAVE_DIR
是指定镜像保存的目录路径,需要根据你的需求进行修改。docker images --format "{{.Repository}}:{{.Tag}}"
获取本地镜像的名称和标签,格式为repository:tag
。for
循环遍历所有镜像,并使用docker save
将每个镜像保存到指定目录,文件名将/
替换为-
,以避免文件名中的非法字符。
使用方法:
- 将上述代码保存为一个
.sh
文件(例如save_images.sh
)。 - 确保脚本有执行权限:
chmod +x save_images.sh
。 - 运行脚本:
./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
说明:
for tar_file in *.tar; do
:遍历当前目录下所有.tar
文件。docker load -i "$tar_file"
:使用docker load
命令加载每个.tar
文件。if [ -e "$tar_file" ]; then
:检查是否有.tar
文件存在,如果存在,则进行加载;如果没有.tar
文件,输出提示信息。
使用方法:
- 将脚本保存为
load_images.sh
。 - 给脚本执行权限:
chmod +x load_images.sh
。 - 运行脚本:
./load_images.sh
。
这个脚本会自动加载当前目录下的所有 .tar
Docker 镜像文件。
从 docker info
输出可以看到你的 Docker 客户端和服务器正常运行,且没有显示出与代理相关的问题。你现在需要通过配置代理来使 Docker 通过 Clash 连接外网。你已经成功验证了 Docker 服务运行正常。
代理配置确认(若路径不存在,自行创建)
-
确保你已经正确配置代理:
- 代理设置需要添加到 Docker 配置文件
~/.docker/config.json
中。 - 如果文件不存在,可以创建它并配置。
- 代理设置需要添加到 Docker 配置文件
-
检查
~/.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" } } }
-
确保 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
如果成功拉取镜像,说明代理配置正确。如果遇到问题,请提供错误信息,我可以继续帮助你排查。
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 连接问题的关联:
-
网络模式 network_mode: "bridge":
-
你使用了默认的 bridge 网络模式。如之前讨论的,这种模式可能对 IPv6 支持不够友好,导致容器无法连接到 mnas.yys.zone 的 IPv6 地址。
-
改进建议:
-
尝试自定义桥接网络,并启用 IPv6: 如前所述,你可以定义一个自定义的桥接网络,并且启用 IPv6,让容器加入这个网络。
-
-
-
缺少 DNS 配置:
-
这个配置中没有指定 DNS 服务器。容器可能会使用默认的 DNS 设置,这可能无法正确解析 mnas.yys.zone 的 IPv6 地址。
-
改进建议:
-
指定 DNS 服务器: 使用 dns 选项,指定 Google 的公共 DNS 服务器, 例如 8.8.8.8 和 2001:4860:4860::8888。
-
-
-
root 用户权限:
-
虽然 user: "root" 可以解决一些权限问题,但它会降低容器的安全性。你应该尽可能避免在容器中使用 root 用户。
-
改进建议:
-
不使用root用户: 可以考虑使用 Jenkins 镜像中默认的 jenkins 用户,如果你需要访问 /home/yys 下的文件,可以修改挂载目录的权限或者修改Jenkins用户拥有/home/yys目录下的文件访问权限。
-
-
-
端口冲突:
-
你映射了多个端口: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
修改步骤:
-
将上面的内容保存到 docker-compose.yml 文件中(或者覆盖你的旧文件)。
-
重新启动你的 docker-compose 项目:
docker-compose down docker-compose up -d
如果修改后仍然存在问题:
-
宿主机网络配置: 确保宿主机正确配置了 IPv6,并且可以访问 mnas.yys.zone 。
-
检查 Jenkins 日志: 查看 Jenkins 容器的日志,查找是否有关于 Git 连接问题的错误信息。
docker logs jenkins
-
检查 端口占用: 检查宿主机端口是否被占用。
通过以上的修改和排查,应该能够解决你 Jenkins 容器 Git 连接的问题。 如果问题仍然存在,请提供更多的信息,我将尽力帮助你。
本文作者: 永生
本文链接: https://yys.zone/detail/?id=215
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
发表评论
评论列表 (0 条评论)
暂无评论,快来抢沙发吧!