概念
Docker核心思想
打包装箱!每个箱子是互相隔离的。
镜像(image):
镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很
多容器。 就好似 Java 中的 类和对象,类就是镜像,容器就是对象!
容器(container):
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的.
启动,停止,删除,基本命令
目前就可以把这个容器理解为就是一个简易的 Linux系统。
仓库(repository):
仓库就是存放镜像的地方!分为公有仓库和私有仓库。(很类似git)
DockerHub(国外)、阿里云 都是容器仓库
Docker和虚拟机技术的不同
- 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
- 每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响
为什么Docker比VM快
新建一个 容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。然而避免引导、加载操作系统内核是个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个复杂的过程,因此新建一个docker容器只需要几秒钟
简单说就是vm新建虚拟机要连同系统硬件的底层系统一起新建,这个过程很慢,但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: 显示镜像的digests信息(sha256)
--no-truc:不截取image id,完全显示
docker images mycentos # 单独查看某一个镜像
docker search mysql # 搜索镜像 对应DockerHub仓库中的镜像
--no-truc: 显示完整 DESCRIPTION
-s 30 列出stars不小于指定值的镜像。
--filter=stars=50 : 也是列出stars不小于指定值的镜像
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 -d --name mycentos centos /bin/bash # 启动centos,且分配一个终端
exit # 退出容器
ctrl+P+Q # 容器不停止退出
docker ps # 列出正在运行的容器
-a # 列出正在运行的容器 + 历史运行过的容器
-l # 显示最近创建的1个容器
-n=? # 显示最近n个创建的容器
-q # 只显示容器id
docker rm 容器id # 删除指定容器 无法删除正在运行的容器就 -f
docker rm -f $(docker ps -a -q) # 删除所有容器
docker start/restart/stop/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 8 仅列出最新8条容器日志
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 较强大,是在容器中打开新的终端,并且可以启动新的进程,追加ls 可以直接不进入cmd列出所有文件
docker exec -it 34hv34h234 ls -l /tmp
# attach 直接进入容器启动命令的终端,不会启动新的进程
docker cp 934e0a1c190c:容器路径 主机路径 # 从容器中复制文件到主机
docker stats id # 容器的cpu内存和网络状态
docker tag diytomcat diy2 # 给diytomcat 增加tag,其实时新生成一个image,命名为diy2
# 注意:commit的时候,容器的名字不能有大写,否则报错:invalid reference format
docker commit -a="vaynexiao" -m="no tomcat docs" 容器id tomcat02:1.1
docker run -it --rm tomcat:9.0 # --rm:容器启动成功并退出以后容器就自动移除,一般测试用
docker run -d -p 8081:8080 --name tomcat9 tomcat # -P 大写p随机分配ip
docker run -d --name mynginx -p 81:80 nginx
curl localhost:81
# 发布镜像到Dockerhub
docker login -u [email protected]
docker push name:tag
# 部署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
mysql -uroot -p
部署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
可视化portainer
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。
数据卷(时刻同步)
数据卷
# 主机和容器都会自动新建不存在的文件夹 (volumes)
docker run -it -v /home/ceshi:/home centos /bin/bash
# ro只读 rw读写
# ro时:只能同步主机的文件查看,并不能vim
# 注意:如果访问出现了 cannot open directory: Permission denied
# 解决办法:在挂载目录后多加一个 --privileged=true参数即可
docker run -it -v /home/ceshi:/home:ro --privileged=true centos /bin/bash
# 查看Mounts挂载信息
docker inspect 09e7b35c4234
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi", # 主机位置
"Destination": "/home", # 容器位置
"Mode": "",
"RW": true, # 可读写
"Propagation": "rprivate"
}
],
数据卷容器
# 制作一个image 挂载目录设置为v1 v2,之后只有挂载目录中文件才会自动同步
FROM centos
# 容器的v1 v2目录,主机上会在对应默认地址生成目录
# /var/lib/docker/volumes/442f7aaf3f84b6b41d4cffc4e3e71a84ab1b89fe9dbe70b76e99f851ff1bf66e/_data
VOLUME ["/v1","/v2"]
CMD echo "-------end------"
CMD /bin/bash
docker run -it --name v1 mycentos
# 多创建几个容器,互相之间错综复杂的挂载
# 此时 v1 v2 v3 v4 都是互通的,不管哪个新建文件都会同步,删除其中一个,也不会影响其他3个的同步功能
# 当然只是之前挂载过得文件夹 v1 v2
docker run -it --name v2 --volumes-from v1 mycentos
docker run -it --name v3 --volumes-from v1 mycentos
docker run -it --name v4 --volumes-from v2 mycentos
匿名挂载 具名挂载
挂载一个本地Linux主机的目录到容器中去,实现容器内数据与本地互通
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 具名挂载
-v 卷名:/容器内路径
docker run -d -P --name nginx02 -v nginxconfig:/etc/nginx nginx
# 指定宿主机的挂载路径
不管匿名还是具名挂载,都会挂载到宿主机的默认路径下,也可以指定宿主机的挂载路径
-v /宿主机路径:/容器内路径
# 查看挂载的路径
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、每条指令都会创建新的镜像层,并提交镜像
FROM # 基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER # 镜像维护者的姓名混合邮箱地址
RUN # 容器构建时需要运行的命令
EXPOSE # 当前容器对外保留出的端口
WORKDIR # 指定在创建容器后,终端默认登录的进来工作目录,落脚点
ENV # 用来在构建镜像过程中设置环境变量
ADD # 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
LABEL #
COPY # 类似ADD,仅仅拷贝文件和目录到镜像中
VOLUME # 容器数据卷,用于数据保存和持久化工作
CMD # 指定一个容器启动时要运行的命令,dockerFile中可以有多个CMD指令,但只有最后一个生效
ENTRYPOINT # 指定一个容器启动时要运行的命令,和CMD一样
ONBUILD # 当构建一个被继承的DockerFile时运行命令,父镜像在被子镜像继承后,父镜像的 ONBUILD被触发
# FROM mycentos # 继承mycentos镜像
实战:自己制作centos
需求:初始centos系统没有vim 没有ifconfig,
FROM centos
MAINTAINER vaynexiao<[email protected]>
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
# .表示生成在当前目录
# -f 不写,会默认找Dockerfile,固定的文件名
docker build -f Dockerfile -t mycentos:2.0 .
docker history 镜像名字 # 列出镜像的生成容器历史记录
docker run -it --name rq-centos0.1 mycentos:2.0
CMD ENTRYPOINT
两个命令都是指定一个容器启动时要运行的命令
CMD:Dockerfile 中可以有多个CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换!
ENTRYPOINT:docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合!
FROM centos
CMD [ "ls", "-a" ]
CDM ls -l
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 安装的压缩包拷贝进上一步目录
jdk-8u271-linux-x64.tar.gz
apache-tomcat-9.0.34.tar.gz
touch read.txt
FROM centos
MAINTAINER vaynexiao<[email protected]>
COPY read.txt /usr/local/readme.txt # 把宿主机当前上下文的read.txt拷贝到容器/usr/local/路径下
ADD jdk-8u271-linux-x64.tar.gz /usr/local/ # 把java与tomcat添加到容器中
ADD apache-tomcat-9.0.34.tar.gz /usr/local/
RUN yum -y install vim # 安装vim编辑器
ENV MYPATH /usr/local
WORKDIR $MYPATH # 设置工作访问时候的WORKDIR路径,登录落脚点
# 配置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
重启访问
http://39.99.164.237:8081/
curl localhost:8081/test/index.jsp
发布镜像到aliyun
# 创建命名空间 - 创建仓库(选择本地仓库)
docker login --username=[email protected] 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:[tag]
docker push registry.cn-zhangjiakou.aliyuncs.com/vaynxiao-docker/for-docker:[tag]
# 速度极慢啊啊。。。
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