感谢:Docker入门学习笔记
简单一句话docker=程序+环境,以往我们开发,往往会为测试环境和运行环境不一致而发愁,在我们测试环境运行非常正常的程序,到了实际环境就失败了,但是docker解决这一问题,docker不仅包含了我们的程序,还将程序依赖的环境一起打包,当我们去一台陌生的服务器操作的时候,只需要使用docker将我们之前打包好的镜像pull到新机器上,就可以迅速的运行
还有一种情况,比如本程序依赖jdk8,另一个程序依赖jdk7等等此类问题,最终都可以使用docker解决.
在这方面,docker就像一台轻量级的虚拟机,我们可以创建多台虚拟机,在一台虚拟机上测试好了程序,复制,打包,把这台虚拟机上传到仓库中,别人再从仓库中下载下来,不用调试,只需开机,程序就能完美的运行
当然docker和虚拟机还是有很大的不同的,最大的好处,就是docker远远小于虚拟机的大小,这样才能方便我们的使用,其他区别大家可以去找其他文章
镜像就是一个只读的模板,可以包含一个完成整的操作系统环境,里面可以安装一些用户需要的应用程序,概念类似VM的镜像。
Docker运行需要本地存在对应的镜像,如果本地无该镜像,Docker会从镜像仓库下载,默认是Docker Hub仓库中心,当然也可以搭建私有仓库将创建好的镜像存到私有仓库供下载使用。
容器是独立运行的一个或一组应用,以及它们的运行态环境。与此对应的是虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。Docker的容器很轻量级(只是运行的一层可写层,所以很多时候用户都是随时删除和新创建容器)
仓库是存放镜像的地方。Docker仓库的镜像管理方式类似Git Hub。Docker官方维护的公共仓库叫Docker Hub,有些功能需要注册。
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
# docker 官方源
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 阿里云源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
出错:
File "/bin/yum-config-manager", line 135
except yum.Errors.RepoError, e:
^
SyntaxError: invalid syntax
此问题可能是之前虚拟机安装过python3的原因,我在一台全新创建的虚拟机上没有遇到
解决:
进入 /bin/yum-config-manager
将第一行改为
#!/usr/bin/python2 -tt
sudo yum install docker-ce docker-ce-cli containerd.io
yum list docker-ce --showduplicates | sort -r
docker-ce.x86_64 3:18.09.1-3.el7 docker-ce-stable
docker-ce.x86_64 3:18.09.0-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.1.ce-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.0.ce-3.el7 docker-ce-stable
yum install docker-ce- docker-ce-cli- containerd.io
例如:
yum install docker-ce-18.09.9-3.el7 docker-ce-cli-18.09.9-3.el7 containerd.io
systemctl start docker
docker run hello-world
解决docker拉取镜像速度过慢问题
进入阿里云网站,搜索docker
service docker start # 启动 docker 服务,守护进程
service docker stop # 停止 docker 服务
service docker status # 查看 docker 服务状态
chkconfig docker on # 设置为开机启动
镜像可以看做我们平时装系统的镜像,里面就是一个运行环境。
docker pull centos:latest # 从docker.io中下载centos镜像到本地
docker images # 查看已下载的镜像
docker rmi image_id # 删除镜像,指定镜像id
# 删除所有镜像(测试不成功)
# none 默认为 docker.io
docker rmi $(docker images | grep none | awk '{print $3}' | sort -r)
# 使用一个镜像开启容器
docker run -t -i nginx:latest /bin/bash
我们可以通过以下两种方式对镜像进行更改。
从已经创建的容器中更新镜像,并且提交这个镜像
使用 Dockerfile 指令来创建一个新的镜像
下面通过已存在的容器创建一个新的镜像。
docker commit -m="First Docker" -a="wcjiang" a6b0a6cfdacf wcjiang/nginx:v1.2.1
上面命令参数说明:
-m
提交的描述信息-a
指定镜像作者a6b0a6cfdacf
记住这个是容器id,不是镜像idzhang/nginx:v1.2.1
创建的目标镜像名假设创建一个 node.js 镜像,首先在 node.js 项目根目录创建文件。
touch Dockerfile .dockerignore
.dockerignore
文件内容,下面代码表示,这三个路径要排除,不要打包进入 image 文件。如果你没有路径要排除,这个文件可以不新建。
.git
node_modules
npm-debug.log
Dockerfile 文件内容
FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000
FROM node:8.4
:该 image
文件继承官方的 node image
,冒号表示标签,这里标签是8.4
,即8.4
版本的 node
。COPY . /app
:将当前目录下的所有文件(除了 .dockerignore
排除的路径),都拷贝进入 image
文件的 /app
目录。WORKDIR /app
:指定接下来的工作路径为/app
。RUN npm install
:在/app目录下,运行 npm install
命令安装依赖。注意,安装后所有的依赖,都将打包进入 image
文件。EXPOSE 3000
:将容器 3000
端口暴露出来, 允许外部连接这个端口。有了 Dockerfile
文件以后,就可以使用 docker image build
命令创建 image
文件了。
$ docker image build -t koa-demo .
# 或者
$ docker image build -t koa-demo:0.0.1 .
上面命令,-t
参数用来指定 image
文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是 latest
。注意后面有个 .
,表示 Dockerfile 文件所在的路径为当前路径
nginx
,打个标签,起个新的名字nginx-test
,/之前就是自己的账户,docker tag zhang/nginx:v1.2.1 刚注册的账户/nginx-test:lastest(latest是版本号,可以自己填写)
docker login
nginx-test
镜像docker push 17862905520/nginx-test:lastest
# The push refers to a repository [docker.io/wcjiang/nginx-test]
# 2f5c6a3c22e3: Mounted from wcjiang/nginx
# cf516324493c: Mounted from wcjiang/nginx
# lastest: digest: sha256:73ae804b2c60327d1269aa387cf782f664bc91da3180d10dbd49027d7adaa789 size: 736
通常情况下,使用docker官方镜像,如 mysql镜像,默认情况下镜像中啥软件也没有,通过下面命令安装你所需要的软件:
# 第一次需要运行这个命令,确保源的索引是最新的
# 同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引
apt-get update
# 做过上面更新同步之后,可以运行下面的命令了
apt-get install vim
如果你安装了CentOS或者Ubuntu系统可以进入系统安装相关软件
# 进入到centos7镜像系统
docker run -i -t centos:7 /bin/bash
yum update
yum install vim
命令格式:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
-d, --detach=false # 指定容器运行于前台还是后台,默认为false
-i, --interactive=false # 打开STDIN,用于控制台交互
-t, --tty=false # 分配tty设备,该可以支持终端登录,默认为false
-u, --user="" # 指定容器的用户
-a, --attach=[] # 登录容器(必须是以docker run -d启动的容器)
-w, --workdir="" # 指定容器的工作目录
-c, --cpu-shares=0 # 设置容器CPU权重,在CPU共享场景使用
-e, --env=[] # 指定环境变量,容器中可以使用该环境变量
-m, --memory="" # 指定容器的内存上限
-P, --publish-all=false # 指定容器暴露的端口
-p, --publish=[] # 指定容器暴露的端口
-h, --hostname="" # 指定容器的主机名
-v, --volume=[] # 给容器挂载存储卷,挂载到容器的某个目录
--volumes-from=[] # 给容器挂载其他容器上的卷,挂载到容器的某个目录
--cap-add=[] # 添加权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cap-drop=[] # 删除权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cidfile="" # 运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法
--cpuset="" # 设置容器可以使用哪些CPU,此参数可以用来容器独占CPU
--device=[] # 添加主机设备给容器,相当于设备直通
--dns=[] # 指定容器的dns服务器
--dns-search=[] # 指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件
--entrypoint="" # 覆盖image的入口点
--env-file=[] # 指定环境变量文件,文件格式为每行一个环境变量
--expose=[] # 指定容器暴露的端口,即修改镜像的暴露端口
--link=[] # 指定容器间的关联,使用其他容器的IP、env等信息
--lxc-conf=[] # 指定容器的配置文件,只有在指定--exec-driver=lxc时使用
--name="" # 指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字
--net="bridge" # 容器网络设置:
# bridge 使用docker daemon指定的网桥
# host //容器使用主机的网络
# container:NAME_or_ID >//使用其他容器的网路,共享IP和PORT等网络资源
# none 容器使用自己的网络(类似--net=bridge),但是不进行配置
--privileged=false # 指定容器是否为特权容器,特权容器拥有所有的capabilities
--restart="no" # 指定容器停止后的重启策略:
# no:容器退出时不重启
# on-failure:容器故障退出(返回值非零)时重启
# always:容器退出时总是重启
--rm=false # 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)
--sig-proxy=true # 设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理
运行一个在后台执行的容器,同时,还能用控制台管理:docker run -i -t -d ubuntu:latest
运行一个带命令在后台不断执行的容器,不直接展示容器内部信息:docker run -d ubuntu:latest ping www.docker.com
运行一个在后台不断执行的容器,同时带有命令,程序被终止后还能重启继续跑,还能用控制台管理,docker run -d --restart=always ubuntu:latest ping www.docker.com
为容器指定一个名字,docker run -d --name=ubuntu_server ubuntu:latest
容器暴露80端口,并指定宿主机80端口与其通信(**:** 之前是宿主机端口,之后是容器需暴露的端口),docker run -d --name=ubuntu_server -p 80:80 ubuntu:latest
指定容器内目录与宿主机目录共享(**:** 之前是宿主机文件夹,之后是容器需共享的文件夹),docker run -d --name=ubuntu_server -v /etc/www:/var/www ubuntu:latest
指明构建的新镜像是来自于哪个基础镜像,例如:
FROM centos:6
指明镜像维护着及其联系方式(一般是邮箱地址),例如:
MAINTAINER Edison Zhou
不过,MAINTAINER并不推荐使用,更推荐使用LABEL来指定镜像作者,例如:
LABEL maintainer="edisonzhou.cn"
构建镜像时运行的Shell命令,例如:
RUN yum install httpd
RUN ["yum", "install", "httpd"]
也就是:
RUN
RUN ["executable", "param1", "param2"]
第二种格式的参数是一个JSON格式的数组,其中"executable"为要运行的命令,后面的"paramN"为传递给命令的选项或参数。此格式指定的命令不会以"/bin/sh -c"来发起,也就是直接由内核创建,因此不具备shell特性,类似于RUN [ “echo”, “$HOME” ],是无法识别 $ 的;如果想要依赖shell特性,可以替换命令为这样的格式[ “/bin/sh”, “-c”, “echo $HOME” ]。
**PS:**多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层.多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错,RUN书写时的换行符是\
启动容器时执行的Shell命令,例如:
CMD ["-C", "/start.sh"]
CMD ["/usr/sbin/sshd", "-D"]
CMD /usr/sbin/sshd -D
声明容器运行的服务端口,例如:
EXPOSE 80 443
设置环境内环境变量,例如:
ENV MYSQL_ROOT_PASSWORD 123456
ENV JAVA_HOME /usr/local/jdk1.8.0_45
**ADD:**拷贝文件或目录到镜像中,例如:
ADD ...
ADD html.tar.gz /var/www/html
ADD https://xxx.com/html.tar.gz /var/www/html
***PS:***如果是URL或压缩包,会自动下载或自动解压。
**COPY:**拷贝文件或目录到镜像中,用法同ADD,只是不支持自动下载和解压,例如:
COPY ./start.sh /start.sh
**PS:**COPY命令用于将宿主机器上的的文件复制到镜像内,如果目的位置不存在,Docker会自动创建。但宿主机器用要复制的目录必须是和Dockerfile文件同目录下。
为RUN、CMD、ENTRYPOINT以及COPY和AND设置工作目录,例如:
WORKDIR /data
为RUN、CMD和ENTRYPOINT执行Shell命令指定运行用户,例如:
USER [:]
USER [:]
USER edisonzhou
**ENTRYPOINT:**ENTRYPOINT的作用和用法和CMD一模一样,但是ENTRYPOINT有和CMD有2处不一样:
ENTRYPOINT ["/bin/bash", "-C", "/start.sh"]
ENTRYPOINT /bin/bash -C '/start.sh'
***PS:***Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效。
**VOLUME:**指定容器挂载点到宿主机自动生成的目录或其他容器,例如:
VOLUME ["/var/lib/mysql"]
***PS:***一般不会在Dockerfile中用到,更常见的还是在docker run的时候指定-v数据卷。
**HEALTHCHECK:**告诉Docker如何测试容器以检查它是否仍在工作,即健康检查,例如:
HEALTHCHECK --interval=5m --timeout=3s --retries=3 \
CMD curl -f http:/localhost/ || exit 1
其中,一些选项的说明:
一些返回值的说明:
**ARG:**在构建镜像时,指定一些参数,例如:
FROM centos:6
ARG user # ARG user=root
USER $user
这时,我们在docker build时可以带上自定义参数user了,如下所示:
docker build --build-arg user=edisonzhou Dockerfile .
下面是一个Java Web应用的镜像Dockerfile,综合使用到了上述介绍中最常用的几个命令:
FROM centos:7
MAINTANIER www.edisonchou.com
ADD jdk-8u45-linux-x64.tar.gz /usr/local
ENV JAVA_HOME /usr/local/jdk1.8.0_45
ADD apache-tomcat-8.0.46.tar.gz /usr/local
COPY server.xml /usr/local/apache-tomcat-8.0.46/conf
RUN rm -f /usr/local/*.tar.gz
WORKDIR /usr/local/apache-tomcat-8.0.46
EXPOSE 8080
ENTRYPOINT ["./bin/catalina.sh", "run"]
有了Dockerfile,就可以创建镜像了:
docker build -t tomcat:v1 .
在使用 COPY 和 ADD 命令时,我们可以通过一些技巧来加速镜像的 build 过程。比如把那些最不容易发生变化的文件的拷贝操作放在较低的镜像层中,这样在重新 build 镜像时就会使用前面 build 产生的缓存。比如笔者构建镜像时需要用到下面几个文件:
其中 myhc.py 文件不经常变化,而 checkmongo.py、checkmysql.py 和 checkredis.py 这三个文件则经常变化,那么我们可这样来设计 Dockerfile 文件:
WORKDIR /app
COPY myhc.py .
COPY check* ./
让 COPY myhc.py . 单独占据一个镜像层,当 build 过一次后,每次因 checkmongo.py、checkmysql.py 和 checkredis.py 这三个文件变化而导致的重新 build 都不会重新 build COPY myhc.py . 镜像层:
如上图所示,第二步和第三步都没有重新 build 镜像层,而是使用了之前的缓存,从第四步才开始重新 build 了镜像层。当文件 size 比较大且文件的数量又比较多,尤其是需要执行安装等操作时,这样的设计对于 build 速度的提升还是很明显的。所以我们应该尽量选择能够使用缓存的 Dockerfile 写法。
touch Dockerfile&&vi Dockerfile
#获取base image
FROM adoptopenjdk/openjdk8:latest
#类似于执行 linux指令
RUN mkdir /opt/app
#类似于linux copy指令,copy同位置的jar包
COPY vr-0.0.1-SNAPSHOT.jar /opt/app/
#对外端口
EXPOSE 8080
#执行命令 java -jar /opt/app/demo-docker.jar
CMD ["java", "-jar", "/opt/app/vr-0.0.1-SNAPSHOT.jar"]
sudo docker build -t docker-demo .
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UNeYY3TU-1586836582819)(D:\自己整理\技术相关文章\图库\docker初学\docker031903.png)]
#我的项目实际上是开放的端口为8092,上面expose:8080但实际应用上没有影响,解释在下面
docker run -it -p 8080:8092 docker-demo
run
运行镜像 -it
以交互模式运行容器并为容器重新分配一个伪输入终端 -p
端口映射,格式为:主机(宿主)端口:容器端口 。 最后的就是我们刚刚创建的镜像名称。
可以看到制作DockerFIle的时候我expose的明明是8080端口号,但下文生成容器的时候内部却使用的是外部的8080映射内部的8092端口号,那DockerFile中的EXPOSE配置还有用吗?
首先,我们最应该明确的一点就是,EXPOSE命令只是声明了容器应该打开的端口并没有实际上将它打开!也就是说,如果你不用-p或者-P中指定要映射的端口,你的容器是不会映射端口出去的,从而我们知道我们是没有办法在Dockerfile里面进行端口映射的,我们只能在容器启动的时候或者在docker-compose文件中使用ports来指定将要映射的端口。
那我们的EXPOSE能用来干什么呢?第一点就是写在Dockerfile中进行声明,能让运维人员或者后来者知道我们开启了容器的哪些端口。还有一点就是,当我们声明了EXPOSE端口之后,我们使用-P命令进行随机映射的时候,是会对这个端口进行映射的。比如说我们现在对一个tomcat容器进行EXPOSE 9999声明,那么我们进行-P随机映射的时候是会对9999端口进行映射的。
现在我们再看:
按照docker run -idt -p 8080:8092 docker-demo
我们可以发现容器的8080端口号是开启的,但是主机没有端口号去映射,所以等同于我们无法访问该端口
按照docker run -idt -P docker-demo
我们可以发现容器的8080端口此时和主机的随机端口形成了映射
# 列出本机正在运行的容器
docker container ls
# 列出本机所有容器,包括终止运行的容器
docker container ls --all
docker start [containerID/Names] # 启动容器
docker stop [containerID/Names] # 停止容器
docker rm [containerID/Names] # 删除容器
docker logs [containerID/Names] # 查看日志
docker exec -it [containerID/Names] /bin/bash # 进入容器
# 从正在运行的 Docker 容器里面,将文件拷贝到本机,注意后面有个【点】拷贝到当前目录
docker container cp [containID]:[/path/to/file] .
docker run centos echo "hello world" # 在docker容器中运行hello world!
docker run centos yum install -y wget # 在docker容器中,安装wget软件
docker ps # 列出包括未运行的容器
docker ps -a # 查看所有容器(包括正在运行和已停止的)
docker logs my-nginx # 查看 my-nginx 容器日志
docker run -i -t centos /bin/bash # 启动一个容器
docker inspect centos # 检查运行中的镜像
docker commit 8bd centos # 保存对容器的修改
docker commit -m "n changed" my-nginx my-nginx-image # 使用已经存在的容器创建一个镜像
docker inspect -f {{.State.Pid}} 44fc0f0582d9 # 获取id为 44fc0f0582d9 的PID进程编号
# 下载指定版本容器镜像
docker pull gitlab/gitlab-ce:11.2.3-ce.0
docker run -itd --name my-nginx2 nginx # 通过nginx镜像,【创建】容器名为 my-nginx2 的容器
docker start my-nginx --restart=always # 【启动策略】一个已经存在的容器启动添加策略
# no - 容器不重启
# on-failure - 容器推出状态非0时重启
# always - 始终重启
docker start my-nginx # 【启动】一个已经存在的容器
docker restart my-nginx # 【重启】容器
docker stop my-nginx # 【停止运行】一个容器
docker kill my-nginx # 【杀死】一个运行中的容器
docker rename my-nginx new-nginx # 【重命名】容器
docker rm new-nginx # 【删除】容器
docker run -itd my-nginx /bin/bash
docker ps
查看到该容器信息docker ps
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 6bd0496da64f nginx "/bin/bash" 20 seconds ago Up 18 seconds 80/tcp high_shirley
docker exec
命令进入一个已经在运行的容器docker exec -it 6bd0496da64f /bin/bash #也可以使用容器的名字 high_shirley
通常有下面几种方式进入Docker的容器,推荐使用exec
,使用attach
一直进入失败。
docker attach
SSH
为什么不需要在 Docker 容器中运行 sshdnsenter
进入Docker容器,nsenter官方仓库docker exec
,在1.3.*
之后提供了一个新的命令exec
用于进入容器从主机复制到容器 sudo docker cp host_path containerID:container_path
从容器复制到主机 sudo docker cp containerID:container_path host_path
docker pull mysql:5.7
docker run -d --name wp-mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 mysql:5.7
docker pull wordpress
docker run -d --name wp --link wp-mysql:mysql -p 80:80 wordpress
本机浏览器访问127.0.0.1
或者打开日志查看另外一个随机的ip
阿里云服务器访问公网地址即可(提前打开80端口)
1.拉取镜像docker pull elasticsearch
2.运行镜像docker run --name=test_es -d -p 9200:9200 -p 9300:9300 elasticsearch:latest
3.出错.内存不足,elasticsearch默认的内存为2G,需要我们修改
4.执行find /var/lib/docker/overlay/ -name jvm.options
**ps:**查不到可以沿着路径去查看,overlay可能版本不同,我的版本为overlay2
5.修改配置即可,将2G改为512m
简洁安装
docker pull mysql:5.7
docker run -d --name wp-mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 mysql:5.7
日志,配置文件等挂载安装
我之前已经安装过mysql,在挂载的时候出现问题,换成不同版本问题消失
在本地创建mysql的映射目录
mkdir -p /root/mysql/data /root/mysql/logs /root/mysql/conf
在/root/mysql/conf中创建 *.cnf 文件(叫什么都行)
touch my.cnf
docker run -d -p 3307:3306 --name mysql -v /root/mysql/conf:/etc/mysql/conf.d -v /root/mysql/logs:/logs -v /root/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
-p 3307:3306:将容器的 3307 端口映射到主机的 3306 端口。
-v $PWD/conf:/etc/mysql/conf.d:将主机目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf。
-v $PWD/logs:/logs:将主机目录下的 logs 目录挂载到容器的 /logs。
-v $PWD/data:/var/lib/mysql :将主机目录下的data目录挂载到容器的 /var/lib/mysql 。
-e MYSQL_ROOT_PASSWORD=123456:初始化 root 用户的密码
我们都知道docker容器之间是互相隔离的,不能互相访问,但如果有些依赖关系的服务要怎么办呢。下面介绍三种方法解决容器互访问题。
安装docker时,docker会默认创建一个内部的桥接网络docker0,每创建一个容器分配一个虚拟网卡,容器之间可以根据ip互相访问。
[root@33fcf82ab4dd /]# [root@CentOS ~]# ifconfig
......
docker0: flags=4163 mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:35ff:feac:66d8 prefixlen 64 scopeid 0x20
ether 02:42:35:ac:66:d8 txqueuelen 0 (Ethernet)
RX packets 4018 bytes 266467 (260.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4226 bytes 33935667 (32.3 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
......
运行一个centos镜像, 查看ip地址得到:172.17.0.7
[root@CentOS ~]# docker run -it --name centos-1 docker.io/centos:latest
[root@6d214ff8d70a /]# ifconfig
eth0: flags=4163 mtu 1500
inet 172.17.0.7 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:7 prefixlen 64 scopeid 0x20
ether 02:42:ac:11:00:07 txqueuelen 0 (Ethernet)
RX packets 16 bytes 1296 (1.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
以同样的命令再起一个容器,查看ip地址得到:172.17.0.8
[root@CentOS ~]# docker run -it --name centos-2 docker.io/centos:latest
[root@33fcf82ab4dd /]# ifconfig
eth0: flags=4163 mtu 1500
inet 172.17.0.8 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:8 prefixlen 64 scopeid 0x20
ether 02:42:ac:11:00:08 txqueuelen 0 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
容器内部ping测试结果如下:
[root@33fcf82ab4dd /]# ping 172.17.0.7
PING 172.17.0.7 (172.17.0.7) 56(84) bytes of data.
64 bytes from 172.17.0.7: icmp_seq=1 ttl=64 time=0.205 ms
64 bytes from 172.17.0.7: icmp_seq=2 ttl=64 time=0.119 ms
64 bytes from 172.17.0.7: icmp_seq=3 ttl=64 time=0.118 ms
64 bytes from 172.17.0.7: icmp_seq=4 ttl=64 time=0.101 ms
这种方式必须知道每个容器的ip,在实际使用中并不实用。
运行容器的时候加上参数link
运行第一个容器
docker run -it --name centos-1 docker.io/centos:latest
运行第二个容器
[root@CentOS ~]# docker run -it --name centos-2 --link centos-1:centos-1 docker.io/centos:latest
–link:参数中第一个centos-1是容器名,第二个centos-1是定义的容器别名(使用别名访问容器),为了方便使用,一般别名默认容器名。
测试结果如下:
[root@e0841aa13c5b /]# ping centos-1
PING centos-1 (172.17.0.7) 56(84) bytes of data.
64 bytes from centos-1 (172.17.0.7): icmp_seq=1 ttl=64 time=0.210 ms
64 bytes from centos-1 (172.17.0.7): icmp_seq=2 ttl=64 time=0.116 ms
64 bytes from centos-1 (172.17.0.7): icmp_seq=3 ttl=64 time=0.112 ms
64 bytes from centos-1 (172.17.0.7): icmp_seq=4 ttl=64 time=0.114 ms
此方法对容器创建的顺序有要求,如果集群内部多个容器要互访,使用就不太方便。
1.安装好docker后,运行如下命令创建bridge网络:docker network create testnet
查询到新创建的bridge testnet。
2.运行容器连接到testnet网络。
使用方法:docker run -it --name <容器名> —network --network-alias <网络别名> <镜像名>
[root@CentOS ~]# docker run -it --name centos-1 --network testnet --network-alias centos-1 docker.io/centos:latest
[root@CentOS ~]# docker run -it --name centos-2 --network testnet --network-alias centos-2 docker.io/centos:latest
3.从一个容器ping另外一个容器,测试结果如下:
[root@fafe2622f2af /]# ping centos-1
PING centos-1 (172.20.0.2) 56(84) bytes of data.
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=1 ttl=64 time=0.158 ms
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=2 ttl=64 time=0.108 ms
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=3 ttl=64 time=0.112 ms
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=4 ttl=64 time=0.113 ms
4.若访问容器中服务,可以使用这用方式访问 <网络别名>:<服务端口号>
推荐使用这种方法,自定义网络,因为使用的是网络别名,可以不用顾虑ip是否变动,只要连接到docker内部bright网络即可互访。bridge也可以建立多个,隔离在不同的网段。