镜像(image):
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像------>run------->tomcat01容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)
容器(container):
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的
启动,停止,删除,基本命令
目前可以把容器理解为一个简易的Linux系统
仓库(repository):
仓库就是存放镜像的地方
仓库分为公有仓库和私有仓库
Docker Hub
阿里云等等都有容器服务器(默认在国外,配置镜像加速)
环境准备
环境查看
# 系统内核是3.10以上的
unmae -r
# 系统版本
cat /etc/os-release
安装
帮助文档
# 1.卸载旧的版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2.需要的安装包
yum install -y yum-utils
# 3.设置镜像的仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo # 默认是国外的,需要换成国内的
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新yum软件包索引
yum makecache fast
# 4. 安装docker相关的 docker-ce 社区版 ee企业版
yum install docker-ce docker-ce-cli containerd.io
# 5.启动docker
systemctl start docker
# 6.使用docker version测试是否安装成功
docker version
# 7.hello-word
docker run hello-word
# 8.查看下载的这个hello-word镜像
docker images
# 1.卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
# 2.删除资源
rm -rf /var/lib/docker
#/var/lib/docker docker的默认工作路径
登录阿里云找到容器服务
找到镜像加速的地址
配置应用
mkdir -p /etc/docker
# 编辑daemon.json
tee /etc/docker/daemon.json <<-'EOF'
# 设置加速器地址
{
"registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
}
EOF
# 最后重新加载和重启docker:
systemctl daemon-reload
systemctl restart docker
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://me0kxh75.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
docker是怎么工作的?
Docker 是一个client-server 结构的系统,Docker的守护进程运行在主机上,通告Socker从客户端访问
Dokcer server 接收到Docker-client 的指令,就会执行这个命令
Docker为什么比虚拟机快
docker version # 显示docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help #万能命令
docker images
# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的ID
CREATED 镜像的创建时间
SIZE 镜像的大小
# 可选项
-a # 列出所有的镜像
-q # 只显示镜像的ID
docker search mysql
# 可选项
--filter=STARS=3000 #搜索出来的镜像是STARS大于3000的
# 下载镜像
docker pull 镜像名[:tag]
如果不写tag,默认就是latest
分层下载,docker image的核心,联合文件系统
Digest #签名
docker.io/library/mysql:latest #真实地址
#等价于他
docker pull mysql
docker pull docker.io/library/mysql:latest
# 指定版本下载
docker pull mysql:5.7
docket rmi -f 镜像id #删除指定镜像
docket rmi -f 镜像id 镜像id #删除多个镜像
docket rmi -f $(docker images -aq) #递归删除所有镜像
说明:我们有了镜像才可以创建容器,Linux,下载一个centos 镜像来测试学习
docker pull centos
docker run [可选参数] image
# 参数说明
--name="Name" # 容器名字 tomcat01 tomcat02,用来区分容器
-d # 后台方式运行
-it # 使用交互方式运行,进入容器查看内容
-p # 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-p # 随机指定端口
# 测试
docker run -it centos /bin/bash # 启动并进入容器
exit # 从容器中退回到主机
docker ps # 列出当前正在运行的容器
-a # 列出当前正在运行的容器+历史运行过的容器
-n=? # 显示最近创建的容器,例如-n=1,显示最近创建的一个容器
-q # 只显示容器的编号
exit # 直接容器停止并退出
ctrl+p+q #容器不停止退出
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,如果想要强制删除 rm -f
docker rm -f $(docker ps -aq) #删除所有的容器
docker ps -a -q|xargs docker rm #删除所有的容器
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
# 命令 docker run -d 镜像名
docker run -d centos
# 问题 docker ps 发现centos停止了
# 常见的坑,docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
docker logs
# 显示日志
-tf #显示全部日志
--tail number #显示指定数量的日志
docker logs -f -t --tail 容器id # 没有日志
#自己编写一段shell脚本
docker run -d centos /bin/bash -c "while true;do echo zjc;sleep 1;done"
docker logs -tf --tail 10 容器id
# 命令 docker top容器id
docker inspect 容器id
# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
#命令
# 方式一
docker exec -it 容器id /bin/bash
# 方式二xi
docker attach 容器id
#区别
docker exec #进入容器之后开启一个新的终端,可以在里面操作(常用)
docker attach # 进入容器正在执行的终端,不会启动新的进程
docker cp 容器id:容器内路径 目的地主机路径
#拷贝是一个手动过程,可以使用-v卷的技术,可以实现
attach # 当前shell下attach连接指定运行镜像
build # 通过dockerfile定制镜像
commit # 提交当前容器为新的镜像
cp # 从容器中拷贝指定文件或者目录到宿主机中
create # 创建一个新的容器,同run 但不启动容器
diff # 查看docker 容器变化
events # 从docker 服务获取容器实时事件
exec # 在已存在的容器上运行命令
export # 导出容器的内容作为一个 tar 归档文件[对应import]
history # 展示一个镜像形成历史
images # 列出系统当前镜像
import # 从tar包中的内容创建一个新的文件系统映像[对应export]
info # 显示系统相关信息
inspect # 查看容器详细信息
kill # kill 指定容器
load # 从一个tar 包中加载一个镜像[对应save]
login # 注册或者登陆一个docker源服务器
logout # 从当前docker registry退出
logs # 输出当前容器日志信息
port # 查看映射端口对应的容器内部源端口
pause # 暂停容器
ps # 列出容器列表
pull # 从docker镜像源服务器拉取指定镜像或者库镜像
push # 推送指定镜像或者库镜像至docker源服务器
restart # 重启运行的容器
rm # 移除一个或者多个容器
rmi # 移除一个或多个镜像[无容器使用该镜像才可删除,否则需要删除相关容器才可继续或 -f 强制删除]
run # 创建一个新的容器并运行一个命令
save # 保存一个镜像为一个tar包[对应load]
search # 在docker hub 中搜索镜像
start # 启动容器
stop # 停止容器
tag # 给源中镜像打标签
top # 查看容器中运行的进程信息
unpause # 取消暂停容器
version # 查看docker版本号
wait # 截取容器停止时的退出状态值
# 1.搜索镜像 search,可以去docker 搜索,可以看到帮助文档
# 2.下载镜像 pull
# 3.运行测试
docker images
# -d 后台运行
# --name 给容器命名
# -p 宿主机端口,容器内部端口
docker run -d --name nginx01 -p 3344:80 nginx
docker ps
curl localhost:3344
# 进入容器
docker exec -it nginx01 /bin/bash
docker stop 容器id
# 思考问题:我们每次改动nginx配置文件,都需要进入容器内部,十分麻烦,我们可以在容器外部提供一个映射路径,到达在容器外部修改文件,容器内部就可以自动修改 -v 数据卷技术
# 官方的使用
docker run -it --rm tomcat:9.0 # 用完就删除
# 我们之前的启动都是后台,停止容器之后,容器还是可以查看到,docker run -it --rm tomcat:9.0
# 下载再启动
docker pull tomcat
# 启动运行
docker run -d -p 3355:8080 --name tomcat101 tomcat
# 测试访问没有问题
# 进入容器
docker exec -it tomcat101 /bin/bash
# 发现问题:1. linux命令少了 2. 没有webapps
# 阿里云镜像的原因,默认是最小的镜像,所有不必要的都删除掉,保证最小可运行的环境
思考:在容器外部提供给一个映射路径,webapps,我们在外部防止项目,就自动同步到内部就好了
# es 暴漏的端口很多
# es 十分的耗内存
# es 的数据一般需要放置到安全目录
# --net somenetwork? 网络配置
# 启动es
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
# 启动了linux 就卡住了,docker stats 查看CPU的状态
# es 十分消耗内存
# 修改配置文件 -e环境配置修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="Xms64m -Xmx512m" elasticsearch:7.6.2
curl localhost:9200
使用kibana连接es,思考网络如何才能连接过去
docker run -d -p 8080:9000 \
--restart=always \-v /var/run/docker.sock:/var/run/docker.sock \--privileged=true portainer/portainer
什么是portainer?
docker run -d -p 8080:9000 \
--restart=always \-v /var/run/docker.sock:/var/run/docker.sock \--privileged=true portainer/portainer
访问测试:http://ip:8080
镜像是一种轻量级、可执行的独立软件保,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软
件所需的所有内容,包括代码、运行时库、环境变量和配置文件
所有的应用,直接打包docker镜像,就可以直接跑起来
**UnionFs(联合文件系统):**Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对
文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite
several directories into a single virtual filesystem)。Union文件系统是 Docker镜像的基础。镜像可以通过分层
来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
**特性:**一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起
来,这样最终的文件系统会包含所有底层的文件和目录
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
boots(boot file system)
主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel, Linux刚启动时会加bootfs文件系统,在 Docker镜像的最底层是 boots。
这一层与我们典型的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发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs.
虚拟机是分钟级别,容器是秒级!
最大的好处,我觉得莫过于资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。
docker image inspect
docker commit 提交容器成为一个新的副本
# 命令
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
实战测试
# 启动一个默认的tomcat
# 发现这个默认的tomcat是没有webapps应用,镜像的原因,官方的镜像默认 webapps下面是没有文件的
# 手动拷贝进去了基本的文件
# 将修改后的容器通过commit提交为一个新的镜像,我们以后就可以使用修改过的镜像,这就是自己修改过的一个镜像
如果想要保存当前容器的状态,我们可以通过commit来提交,获得一个镜像,类似于虚拟机的快照
docker的理念回顾
将应用和环境打包成一个镜像
如果数据都在容器中,那么删除容器,数据就会丢失! 需求:数据可以持久化
MySQL,容器删了,删库跑路!需求:MySQL数据可以存储在本地
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!!目录的挂载,将我们容器内的目录,挂载到Linux上面
容器的持久化和同步操作!容器之间也是可以数据共享的
docker run -it -v 主机目录:容器内目录
# 测试
docker run -it -v /home/ceshi:/home centos /bin/bash
# 启动起来之后,我们可以通过 docker inspect 容器id 来查看元数据
# 再次测试
1. 停止容器
2. 在宿主机上修改文件
3. 再次启动容器
4. 容器内的数据依旧是同步的
好处:
我们以后修改只需要在本地修改即可,容器内自动同步!
# 获取镜像
docker pull mysql:5.7
# 运行容器,数据挂载 # 安装启动mysql,需要配置密码!!!
# 官方测试:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 运行容器,数据挂载 # 安装启动mysql,需要配置密码!!!
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
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:5.7
# 启动成功之后,我们在本地使用sql yog测试连接
# sqlyog 连接到服务器的3310 --- 3310和容器内的3306映射,这个时候就可以连接上了
# 在本地测试创建一个数据库,查看一下我们映射的路径是否OK
发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看所有的volume的情况
➜ ~ docker volume ls
DRIVER VOLUME NAME
local 33ae588fae6d34f511a769948f0d3d123c9d45c442ac7728cb85599c2657e50d
# 这里发现,这种就是匿名挂载,我们在 -v只写了容器内的路径,没有写容器外的路径!
# 具名挂载
➜ ~ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
➜ ~ docker volume ls
DRIVER VOLUME NAME
local juming-nginx
# 通过 -v 卷名:容器内路径
# 查看一下这个卷
docker volume inspect juming-nginx
# 所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxx/_data,如果指定了目录,docker volume ls 是查看不到的
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用的是具名挂载
# 三种挂载: 匿名挂载、具名挂载、指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的
# 通过 -v 容器内路径:ro rw 改变读写权限
ro #read only 只读
rw #read write 可读可写
# 一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
Dockerfile就是用来构建docker镜像的构建文件、命令脚本
通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层
# 创建一个dockerfile文件,名字可以随便 建议Dockerfile
# 文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
#这里的每个命令,就是镜像的一层!
docker build -f /dockerfile -t kuangshen/centos:v1.0 .
# 启动容器
这个卷和外部有一个同步的目录
查看一下挂载的路径
测试一下刚才的文件是否同步
这种方式之后使用的很多,因为 通常我们会构建自己的镜像
假设构建镜像的时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径
多个mysql同步数据
# 启动三个容器,通过我们自己写的容器
docker run -it --name docker01 kuangshen/centos:1.0
# 此时删除容器docker01,docker02和docker03依旧可以访问这个文件
拷贝的概念
多个mysql实现数据共享
docker run -d -p 3306:3306 -v /etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
# 这个时候,可以实现两个容器数据同步!
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止
但是一旦持久化到了本地,这个时候本地的数据是不会删除的
dockerfile是用来构建docker镜像的文件,命令参数脚本
很多官方镜像都是基础包,很多功能都没有,我们通常自己搭建自己的镜像
Dockerfile是面向开发的,以后发布项目,做镜像,就需要编写dockerfile文件
Docker镜像逐渐成为企业交付的标准
Dockerfile:构建文件,定义了一切的步骤,源代码
Dockerimages:通告Dockerfile构建生成的镜像,最终发布运行的产品
Docker容器:容器就是镜像运行起来提供服务
FROM # 基础镜像,一切从这开始构建
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 添加内容
WORKDIR # 镜像的工作命令
VOLUME # 挂载的目录
EXPOSE # 指定暴露端口
CMD # 指定容器启动的时候运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令可以追加命令
ONBUILD # 当构建一个被继承的 dockerfile ,这个时候就会运行ONBUILD的指令,触发指令
COPY # 类似ADD,将我们的文件拷贝到镜像中
ENV # 构建的时候设置环境变量
Docker Hub中99%镜像都是从这个基础镜像过来的 FROM scratch,然后配置需要的软件和配置来进行构建
# 1.编写Dcokerfile文件
vim mydockerfile-centos
FROM centos
MAINTAINER zhaojinchao<[email protected]>
ENV MYPATH /usr/loacl
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash
# 2.通过这个文件构建镜像
# 命令:docker build -f dockerfile文件路径 -t 镜像名:[tag] .
docker build -f mydockerfile-centos -t mycentos:0.1 .
# 3.测试运行
我们可以通过 docker history+镜像id 列出本地镜像的变更历史
我们平时拿到一个镜像,可以研究一下他是怎么做到的
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
# 编写dockerfile文件
vi dockerfile-cmd-test
FROM centos
CMD ["ls","-a"]
# 构建镜像
docker build -f dockerfile-cmd-test -t cmdtest .
# RUN运行,发现我们的ls -a命令生效
docker run dd8e4401d72f
# 想追加一个命令 -l,成为ls -al
docker run dd8e4401d72f -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\":
executable file not found in $PATH": unknown.
ERRO[0000] error waiting for container: context canceled
# cmd的情况下 -l 替换了CMD["ls","-l"]。 -l 不是命令所有报错
# 编写dockerfile文件
$ vim dockerfile-cmd-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
$ docker build -f dockerfile-cmd-entrypoint -t entrypoint-test .
$ docker run 3c4c9621ed91
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found ...
# 我们的命令,是直接拼接在我们得ENTRYPOINT命令后面的
$ docker run entrypoint-test:0.1 -l
total 56
drwxr-xr-x 1 root root 4096 May 16 06:32 .
drwxr-xr-x 1 root root 4096 May 16 06:32 ..
-rwxr-xr-x 1 root root 0 May 16 06:32 .dockerenv
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 340 May 16 06:32 dev
drwxr-xr-x 1 root root 4096 May 16 06:32 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64 ....
1. 准备镜像文件 tomcat 压缩包,jdk的压缩包
2. 编写dockerfile文件,官方命名Dockerfile,build会自动寻找这个文件,不需要再-f指定
FROM centos
MAINTAINER chao # 名字
COPY readme.txt /usr/local/readme.txt #复制文件
ADD jdk-8u231-linux-x64.tar.gz /usr/local/ #复制解压
ADD apache-tomcat-9.0.35.tar.gz /usr/local/ #复制解压
RUN yum -y install vim
ENV MYPATH /usr/local #设置环境变量
WORKDIR $MYPATH #设置工作目录
ENV JAVA_HOME /usr/local/jdk1.8.0_11 #设置环境变量
ENV CLASSPATH $JAVA_HOME/bin/dt.jar:$JAVA_HOME/lib/tools.jar #设置环境变量 分隔符是:
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 #设置环境变量
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.35 #设置环境变量
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080 #设置暴露的端口
CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.35/bin/logs/catalina.out # 设置默认命令
3. 构建镜像
docker build -t diytomcat .
4. 运行
$ docker run -d -p 9090:8080 --name kuangshentomcat -v /home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test -v /home/kuangshen/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs diytomcat
5、访问测试
6、发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了!)
vi web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
web-app>
vi index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
JC
Hello World!
<%
sysem.out.println("---my test web logs---")
%>
提交的时候也是按照镜像的层级来进行提交的
$ docker login --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username
# 登录
dokcer login -u 用户名
# 上传镜像
docker push 镜像名
# push镜像的问题
会发现push不上去,因为如果没有前缀的话默认是push到 官方的library
# 解决方法
1. 第一种 build的时候添加你的dockerhub用户名,然后在push就可以放到自己的仓库了
$ docker build -t chengcoder/mytomcat:0.1 .
2. 第二种 使用docker tag 然后再次push
$ docker tag 镜像id chengcoder/mytomcat:1.0 #然后再次push
阿里云容器镜像的就参考官方地址
三个网络
# 问题:docker 是如何处理容器网络访问的
# 测试 运行一个tomcat
docker run -d -P --name tomcat01 tomcat
# 查看容器的内部的网络地址 ip addr
docker exec -it 容器id ip addr
# 查看容器内部网络地址 发现容器启动的时候会得到一个 eth0@if551 ip地址,docker分配!
550: eth0@if551: <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
# 思考? linux能不能ping通容器内部! 可以 容器内部可以ping通外界吗? 可以!
$ 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.069 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.074 ms
# 我们发现这个容器带来的网卡,都是一对一对出现的
# evth-pair 就是一对的虚拟设备接口,都是成对出现的,一段连着协议,一段彼此相连
# 正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的
# Openstack,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
docker exec -it tomcat02 ping 172.18.0.2
# 结论:容器和容器之间是可以相互ping通的
结论: tomcat01 和 tomcat02 是共用的一个 docker0
所有的容器不指定网络的情况下,都是通过docker0通信的,docker会给我们的容器分配一个默认的可用IP
Docker使用的是Linux的桥接,宿主机中是一个Dokcer容器的网桥 docker0
Dcoker中的所有的网络接口都是虚拟的,虚拟的转发效率高
只要容器删除,对应网桥一对就都没了
场景:编写了一个微服务,项目不重启,数据库 IP 换掉了,如何用名字来进行访问容器
$ docker exec -it tomcat02 ping tomca01 # ping不通
ping: tomca01: Name or service not known
# 如何解决?
通过 --link 解决了网络连通问题
# 运行一个tomcat03 --link tomcat02
$ docker run -d -P --name tomcat03 --link tomcat02 tomcat
5f9331566980a9e92bc54681caaac14e9fc993f14ad13d98534026c08c0a9aef
# 用tomcat03 ping tomcat02 可以ping通
$ docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.115 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.080 ms
# 用tomcat02 ping tomcat03 ping不通
探究:inspect
# 查看hosts 配置
–link 就是在我们hosts配置中增加了一个 172.18.0.3 tomcat02 312857784cd4
现在已经不建议使用 --link 了
docker0的问题:不支持容器名连接网络
查看所有的docker 网络
网络模式:
1. bridge:桥接(默认)
2. none:不配置网络
3. host:和宿主机共享网络
4. container:容器网络互通(用的少,局限大)
测试:
# 我们直接启动的命令默认有--net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
等价于---> docker run -d -P --name tomcat01 --net bridge tomcat
# docker0 特点:默认bridge,域名不能访问, --link可以打通连接,但不推荐使用
# 我们可以自定义一个网络
自定义一个网络
# --driver bridge
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
docker network ls
# 我们的网络就创建好了
docker network inspect mynet
# 测试
docker run -d -P --name tomcat-net-01 --network mynet tomcat
docker run -d -P --name tomcat-net-02 --network mynet tomcat
# 自定义的网络可以直接ping 通, 不需要使用 --link
redis:不同的集群使用不同 的网络,保证集群是安全和健康的
mysql:不同的集群使用不同的网络,保证集群是安全和健康的
# 测试打通 tomcat01 - mynet
docker network connect mynet tomcat01
# 连通之后就是将 tomcat01 放到了 mynet 网络下
# 一个容器两个ip地址
# 创建网卡
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
# 通过脚本运行六个redis
for port in $(seq 1 6);\
docker run -p 637${port}:6379 -p 1667${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 exec -it redis-1 /bin/sh #redis默认没有bash
# 创建集群
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