概念
Docker核心思想
打包装箱!每个箱子是互相隔离的。
镜像(image):
Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很
多容器。 就好似 Java 中的 类和对象,类就是镜像,容器就是对象!
容器(container):
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的.
启动,停止,删除,基本命令
目前就可以把这个容器理解为就是一个简易的 Linux系统。
仓库(repository):
仓库就是存放镜像的地方!
仓库分为公有仓库和私有仓库。(很类似git)
Docker Hub是国外的。
阿里云…都有容器服务器(配置镜像加速!)
Docker和虚拟机技术的不同
- 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
- 每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响
为什么Docker比Vm快
新建一个 容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。然而避免引导、加载操作系统内核是个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个复杂的过程,因此新建一个docker容器只需要几秒钟
卸载 安装 启动
# 确定你是CentOS7及以上版本
cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
# yum安装gcc相关(需要确保可以上外网 )
yum -y install gcc
yum -y install gcc-c++
#################################### 卸载 #######################################
systemctl stop docker # 先停止服务
yum list installed | grep docker # 列出已安装的docker程序
containerd.io.x86_64 1.3.7-3.1.el7 @docker-ce-stable
docker-ce.x86_64 3:19.03.13-3.el7 @docker-ce-stable
docker-ce-cli.x86_64 1:19.03.13-3.el7 @docker-ce-stable
yum remove docker-ce.x86_64 docker-ce-cli.x86_64 -y # 卸载已安装的2个程序
rm -rf /var/lib/docker # 还要删除镜像/容器等
# 这也是卸载和上面啥区别呢
yum -y remove docker docker-common docker-selinux docker-engine
# 这也是卸载,,天哪
yum -y remove docker-ce docker-ce-cli containerd.io
# 这又是卸载和上面啥区别呢
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
#################################### yum安装 (推荐) ############################
# 官网安装参考手册:https://docs.docker.com/install/linux/docker-ce/centos/
# 安装需要的环境
yum install -y yum-utils device-mapper-persistent-data lvm2
# 设置stable镜像仓库/设置yum源
# /etc/yum.repos.d 文件夹下会生成 CentOS-Base.repo
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo #官网,速度慢
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #推荐使用aliyun,速度快
yum makecache fast # 更新yum软件包索引
# 查看所有仓库中所有docker版本,并选择特定版本安装
yum list docker-ce --showduplicates | sort -r # 有很多版本
# 安装 Docker CE
yum -y install docker-ce-17.12.0.ce # 指定版本安装:特别注意docker-ce-17.12.0.ce是怎么组合的
yum -y install docker-ce docker-ce-cli containerd.io # 默认下载最新版本Docker CE 且安装
systemctl start docker # 启动docker,但只是当下临时启动
systemctl enable docker # 设置为开机启动
docker version # 有client和service两部分表示docker安装启动成功
systemctl status docker # 查看docker启动状态
ps -ef|grep -i docker # 查看正在进行的docker进程
yum list installed | grep docker # 查看已安装的docker程序
docker run hello-world # 优先本地找hello-world,在取gockerhub找,找到启动,找不到报错
docker images # 列出所有镜像
#################################### tar安装 ??(待补充) ######################################
#################################### 配置镜像加速 ######################################
# 这是阿里云控台制生成的,直接去复制,每个人都是不一样的
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://qiyb9988.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
################################ 其他命令 ######################################
docker version # 显示 Docker 版本信息。
docker info # 显示 Docker 系统信息,包括镜像和容器数。。
docker --help # 帮助
docker xxx --help ##
镜像命令 容器命令
docker images # 列出本地镜像
-a: 列出本地所有镜像
-q: 只显示镜像id
--digests: 显示镜像的摘要信息
docker search mysql # 搜索镜像 对应DockerHub仓库中的镜像
--filter=stars=50 : 列出收藏数不小于指定值的镜像。
docker pull mysql # 下载镜像
docker pull mysql:5.7 # 指定版本
docker rmi -f bc9a0695f571 # 根据id删除镜像
docker rmi -f hello-world:latest mysql:5.7 # 根据名字和tag删除镜像
docker rmi -f $(docker images -qa) # 全部删除
docker run [OPTIONS] IMAGE [COMMAND][ARG...] # 使用到了镜像
--name="Name" # 给容器指定一个名字 -d # 后台方式运行容器,并返回容器的id!
-i # 以交互模式运行容器,通过和 -t 一起使用
-t # 给容器重新分配一个终端,通常和 -i 一起使用
-P # 随机端口映射(大写) -p # 指定端口映射(小结),一般可以有四种写法
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort (常用)
containerPort
docker run -it centos /bin/bash # 启动centos,且分配一个终端
exit # 退出容器
ctrl+P+Q # 容器不停止退出
docker ps # 列出正在运行的容器
-a # 列出正在运行的容器 + 历史运行过的容器
-l # 显示最近创建的容器
-n=? # 显示最近n个创建的容器
-q # 静默模式,只显示容器编号。
docker rm 容器id # 删除指定容器 无法删除正在运行的容器就 -f
docker rm -f $(docker ps -a -q) # 删除所有容器
docker start (容器id or 容器名) # 启动容器
docker restart (容器id or 容器名) # 重启容器
docker stop (容器id or 容器名) # 停止容器
docker kill (容器id or 容器名) # 强制停止容器
docker run -d centos # 启动centos,使用后台方式启动,但没有前台进程,会自杀
# 这里表示永不停歇的打印语句,这样有了进程这个容器就不会自动关闭 docker ps 才能查得到
docker run -d centos /bin/bash -c "while true;do echo kuangshen;sleep 1;done"
docker logs -f -t --tail 10 3c5bb777ad9c # 获取容器的日志 (此时容器中没有做任何事,所以日志为空)
-f : 跟踪日志输出
--since :显示某个开始时间的所有日志
-t : 显示时间戳
--tail :仅列出最新N条容器日志 需要一个num
docker logs -tf --tail 10 39455ce3cd05 # 查看前十条日志
docker inspect 容器id # 查看容器/镜像的元数据(内容很多很多。。。)
docker top 容器id # 查看容器中运行的进程信息
UID PID PPID C STIME TTY TIME CMD
root 27437 27421 0 16:43 ? 00:00:00 /bin/sh -c ....
docker exec -it 容器id /bin/bash # 进入正在运行的容器
docker attach 容器id # 也是进入容器
# exec 是在容器中打开新的终端,并且可以启动新的进程
# attach 直接进入容器启动命令的终端,不会启动新的进程
docker cp 934e0a1c190c:/home/home.java /home # 从容器中复制文件到主机
docker stats id # 容器的cpu内存和网络状态
docker hitory 镜像名字 # 列出镜像的生成容器历史记录
docker tag diytomcat diy2 # 给diytomcat 增加tag,其实时新生成一个image,命名为diy2
部署Nginx
docker pull nginx
docker run -d --name mynginx -p 81:80 nginx
curl localhost:81
部署Tomcat
额外知识:
# -it :交互模式
# --rm:容器启动成功并退出以后容器就自动移除,一般在测试情况下使用!
docker run -it --rm tomcat:9.0
docker pull tomcat
docker run -d -p 8080:8080 --name tomcat9 tomcat
docker exec -it mytomcat /bin/bash
部署ES
docker run -d --name myes -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2 # es装了后很占内存
docker run -d --name minEs -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
curl localhost:9200
可视化
docker run -d -p 9001:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
Portainer是Docker的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷
的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm集群和
服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型单位对容器管
理的全部需求。
如果仅有一个docker宿主机,则可使用单机版运行,Portainer单机版运行十分简单,只需要一条语句即
可启动容器,来管理该机器上的docker镜像、容器等数据。
curl localhost:9001
镜像加载原理
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,
它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系
统下(unite several directories into a single virtual filesystem)。
Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,
基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件
系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启
动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是
一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已
由bootfs转交给内核,此时系统也会卸载bootfs。 rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标
准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
对于一个精简的OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直
接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版, bootfs基本是一
致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。
Commit镜像
# 注意:commit的时候,容器的名字不能有大写,否则报错:invalid reference format
docker commit -a="kuangshen" -m="no tomcat docs" 容器id tomcat02:1.1
数据卷
容器数据卷
1. 停止容器
2. 在宿主机上修改文件,增加些内容
3. 启动刚才停止的容器
4. 然后查看对应的文件,发现数据依旧同步!
docker run -it -v /home/ceshi:/home centos /bin/bash
docker inspect 09e7b35c4234
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi", # 主机位置
"Destination": "/home", # 容器位置
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
数据卷容器
# 制作一个image 挂载目录设置为v1 v2,之后只有挂载目录中文件才会自动同步
FROM centos
VOLUME ["/v1","/v2"]
CMD echo "-------end------"
CMD /bin/bash
docker run -it --name v1 v-centos # run 一个rq1
docker run -it --name v2 --volumes-from v1 v-centos # run 一个v2
docker run -it --name v3 --volumes-from v2 v-centos # run 一个v3
此时3 2 1 都打通了,时刻文件保持一致
区别
容器数据卷
已经有了容器后,额外配置一个挂在目录 -v /home/ceshi:/home
数据卷容器
生成容器时,顺带配置挂在目录 v2 --volumes-from v1
前者时单独指定一个同步目录,容器本身功能还要发挥;
后者作为一个单独容器,主要是为了同步数据而已,也就是只玩设置的挂在目录而已
部署Mysql 同步数据
docker run -d -p 3307:3306 -v /home/ceshi/mysql/conf:/etc/mysql/conf.d -v /home/ceshi/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# -v 配置了映射路径
docker rm -f mysql01
-v 主机目录:容器目录 这种方式不能够直接在 DockerFile中实现。
# vim dockerf1
FROM centos
VOLUME ["/v1","/v2"]
CMD echo "-------end------"
CMD /bin/bash
docker build -f /root/dockerf1 -t v-centos .
注意:如果访问出现了 cannot open directory: Permission denied
解决办法:在挂载目录后多加一个 --privileged=true参数即可
匿名挂载 具名挂载
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 具名挂载
-v 卷名:/容器内路径
docker run -d -P --name nginx02 -v nginxconfig:/etc/nginx nginx
# 查看挂载的路径
docker volume inspect nginxconfig
[
{
"CreatedAt": "2020-05-13T17:23:00+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/nginxconfig/_data",
"Name": "nginxconfig",
"Options": null,
"Scope": "local"
}
]
# 怎么判断挂载的是卷名而不是本机目录名?
不是/开始就是卷名,是/开始就是目录名
# 改变文件的读写权限
# ro: readonly
# rw: readwrite
# 指定容器对我们挂载出来的内容的读写权限
docker run -d -P --name nginx02 -v nginxconfig:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v nginxconfig:/etc/nginx:rw nginx
Dockerfile
1、每条保留字指令都必须为大写字母且后面要跟随至少一个参数
2、指令按照从上到下,顺序执行
3、# 表示注释
4、每条指令都会创建一个新的镜像层,并对镜像进行提交
执行类似 docker commit 的操作提交一个新的镜像层,再基于刚提交的镜像运行一个新容器
FROM # 基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER # 镜像维护者的姓名混合邮箱地址
RUN # 容器构建时需要运行的命令
EXPOSE # 当前容器对外保留出的端口
WORKDIR # 指定在创建容器后,终端默认登录的进来工作目录,一个落脚点
ENV # 用来在构建镜像过程中设置环境变量
ADD # 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY # 类似ADD,拷贝文件和目录到镜像中!
VOLUME # 容器数据卷,用于数据保存和持久化工作
CMD # 指定一个容器启动时要运行的命令,dockerFile中可以有多个CMD指令,但只有最 后一个生效!
ENTRYPOINT # 指定一个容器启动时要运行的命令!和CMD一样
ONBUILD # 当构建一个被继承的DockerFile时运行命令,父镜像在被子镜像继承后,父镜像的 ONBUILD被触发
实战:初始centos系统没有vim 没有ifconfig,自己制作centos
vim mydockerfile-centos
FROM centos
MAINTAINER kuangshen<24736743@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "----------end--------"
CMD /bin/bash
docker build -f mydockerfile-centos -t mycentos:0.1 . # .表示生成在当前目录
docker run -it --name rq-centos0.1 mycentos:0.1
CMD ENTRYPOINT
两个命令都是指定一个容器启动时要运行的命令
CMD:Dockerfile 中可以有多个CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换!
ENTRYPOINT:docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合!
FROM centos
CMD [ "ls", "-a" ]
docker build -f dockerfile-cmd-test -t cmdtest .
docker run 554bc6952657 # 会顺便执行ls -a
docker run cmdtest -l # 此时会报错
制作Tomcat镜像
mkdir -p /home/build/tomcat
cd /home/build/tomcat
将 JDK 和 tomcat 安装的压缩包拷贝进上一步目录
touch read.txt
# 新建一个Dockerfile文件
FROM centos
MAINTAINER vaynexiao<576583212@qq.com>
#把宿主机当前上下文的read.txt拷贝到容器/usr/local/路径下
COPY read.txt /usr/local/readme.txt
#把java与tomcat添加到容器中
ADD jdk-8u271-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.34.tar.gz /usr/local/
#安装vim编辑器
RUN yum -y install vim
#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local WORKDIR $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_271
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.34
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.34
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.34/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-9.0.34/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.34/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.34/bin/logs/catalina.out
docker build -t diytomcat .
docker run -d -p 8081:8080 --name rongqi-diytomcat2 -v /home/build/tomcat/test:/usr/local/apache-tomcat-9.0.34/webapps/test -v /home/build/tomcat/tomcat9logs/:/usr/local/apache-tomcat-9.0.34/logs --privileged=true diytomcat
curl localhost:8081
在/home/build/tomcat/test下
vim index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>hello,kuangshen</title> </head> <body> -----------welcome------------ <%=" my docker tomcat,kuangshen666 "%> <br> <br> <% System.out.println("-------my docker tomcat-------");%> </body> </html>
重启访问
http://39.99.164.237:8081/
curl localhost:8081/test/index.jsp
发布镜像到Dockerhub
docker login -u name
docker push name:tag
发布镜像到aliyun
# 创建命名空间 - 创建仓库(选择本地仓库)
docker login --username=a576583****@163.com registry.cn-zhangjiakou.aliyuncs.com # 这里星号要重写清楚
# registry.cn-zhangjiakou.aliyuncs.com/vaynxiao-docker/for-docker 是阿里固定的
docker tag [ImageId] registry.cn-zhangjiakou.aliyuncs.com/vaynxiao-docker/for-docker:[镜像版本号]
docker push registry.cn-zhangjiakou.aliyuncs.com/vaynxiao-docker/for-docker:[镜像版本号]
# 速度极慢啊啊。。。
Docker网络
通信原理
docker run -d -P --name tomcat01 tomcat # 容器1 tomcat01
docker run -d -P --name tomcat02 tomcat # 容器2 tomcat02
docker exec -it tomcat01 ip addr
docker可以ping通自己的容器
每一个安装了Docker的linux主机都有一个docker0的虚拟网卡。这是个桥接网卡,使用了veth-pair技术!
docker exec -it tomcat01 ip addr # 成对出现 514-515 516-517 这就是evth-pair技术
docker exec -it tomcat02 ip addr
[root@iZ8vb9yzkqg41m0qu0ix71Z]# 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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:0d:5f:1d brd ff:ff:ff:ff:ff:ff
inet 172.26.207.31/20 brd 172.26.207.255 scope global dynamic eth0
valid_lft 315018187sec preferred_lft 315018187sec
515: veth180d89c@if514: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 96:f6:e4:e8:e0:56 brd ff:ff:ff:ff:ff:ff link-netnsid 0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:7a:5f:c7:03 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
517: vethbfc12c4@if516: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether a2:c0:7d:14:ac:29 brd ff:ff:ff:ff:ff:ff link-netnsid 1
[root@iZ8vb9yzkqg41m0qu0ix71Z]# 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
514: eth0@if515: <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
valid_lft forever preferred_lft forever
[root@iZ8vb9yzkqg41m0qu0ix71Z]# 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
516: eth0@if517: <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
valid_lft forever preferred_lft forever
# evth-pair负责连接容器与docker,所以容器之间也可以ping通
00000000.00000000.00000000.00000000
255.255.0.1/16 # 域 前16位是网段
255*255 - 0.0.0.0 - 255.255.255.255 = 6w多
Docker容器网络就很好的利用了Linux虚拟网络技术,在本地主机和容器内分别创建一个虚拟接口,并
让他们彼此联通(这样一对接口叫veth pair),所以局域网传输速度极快。
–Link (过时)
# --link 过时 不推荐使用 使用自定义网络
微服务中通信需要设置ip:port,每次docker启动的服务ip自动分配,会变化,通过ip连接肯定不可行
[root@kuangshen ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known # 发现ping不通
[root@kuangshen ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
a3a4a17a2b707766ad4f2bb967ce1d94f658cd4cccef3bb8707395cdc71fa1e7
--link是单向连接,用tomcat2是无法ping通tomcat3的
docker network ls # docker0的网络是bridge
docker inspect images-id/container-id # 查看网络信息
原理是什么呢?我们进入tomcat03中查看下host配置文件 (注意是设置了tomcat03 --link tomcat02)
[root@kuangshen ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.3 tomcat02 b80da266a3ad # 发现tomcat2直接被写在这里
172.18.0.4 a3a4a17a2b70
# 所以这里其实就是配置了一个 hosts 地址而已!
# 原因:--link的时候,直接把需要link的主机的域名和ip直接配置到了hosts文件中了。
自定义网络
查看一个具体的网络的详细信息
docker network inspect 4eb2182ac4b2 # docker network inspect mynet
docker rm -f $(docker ps -aq) 删除原来的所有容器
# 默认我们不配置网络,也就相当于默认值 --net bridge 使用的docker0
docker run -d -P --name tomcat01 --net bridge tomcat
# docker0网络的特点
1.它是默认的
2.域名访问不通
3.--link 域名通了,但是删了又不行
# 自定义创建的默认default "bridge"
# 自定义创建一个网络网络
[root@kuangshen ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
09bd09d8d3a6b33e6d19f49643dab551e5a45818baf4d5328aa7320c6dcfc236
docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat
# 同在一个网段,自然可以通信,此时通过容器面也可以通信
docker exec -it tomcat-net-01 ping tomcat-net-02
网络联通
# 要跨网络操作,比如tomcat1想要连接tomcat-net-01,先要加入mynet网络
docker network connect mynet tomcat01 # docker network connect net container
docker network inspect mynet # 发现tomcat01被加入mybet,tomcat01拥有了双ip
Redis集群
# 高可用 集群,master挂了,slave自动顶上(不知道slave顶不顶得住)
# 创建网卡
docker network create redis --subnet 172.38.0.0/16
# 通过脚本创建六个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 ${port}:6379 -p ${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server
/etc/redis/redis.conf; \
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
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
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
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
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
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
# 进入一个redis,注意这里是 sh命令
docker exec -it redis-1 /bin/sh
# 创建集群
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
## ???[ERR] Node 172.38.0.11:6379 is not configured as a cluster node.
cluster-enabled yes
appendonly yes
???这两个已经设置了
# 连接集群 (要在/data下执行,即docker exec进入的路径)
redis-cli -c
# 进入某一个redis 查看集群信息
cluster info
# 进入某一个redis 查看节点
cluster nodes # 会发现自动分配3主3从
set a b
# 假设被存入3号容器,然后docker stop id
# 然后再次get a,发现从3号容器的slave容器中获取值
# 查看节点
3号 fail
slave 成为 master
部署Springboot微服务项目
# springboot 只有/hello请求 得到jar
# 1,IDEA安装插件docker 为了写Dockerfile语法高亮,
在项目下编写 Dockerfile 文件,将打包好的jar包拷贝到Dockerfile同级目录
FROM java:8
# 服务器只有dockerfile和jar在同级目录
COPY *.jar /app.jar
CMD ["--server.port=8080"]
# 指定容器内要暴露的端口
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
# 2、编写Dockerfile
[root@kuangshen]# pwd
/home/idea
[root@kuangshen]# ll ftp上传至jar + Dockerfile
total 17228
-rw-r--r-- 1 root root 17634294 May 14 12:33 demo-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root 207 May 14 12:32 Dockerfile
docker build -t idea-ks . # 构建镜像
docker images # 查看镜像
docker run -d -P --name rq-idea-ks idea-ks # 运行
[root@kuangshen ~]# docker ps
CONTAINER ID IMAGE PORTS NAMES
2366c960ba99 idea-ks 0.0.0.0:32779->8080/tcp rq-idea-ks1
# 测试访问
[root@kuangshen ~]# curl localhost:32779
[root@kuangshen ~]# curl localhost:32779/hello