Docker概述
环境配置问题
问题:为什么这个程序在我的电脑上可用运行,在另一台电脑上无法运行?
Java程序必须安装JDK才可以编译运行,如果另一台电脑没有JDK就无法运行了
那有什么办法可以解决这个呢?
项目可以带上环境(镜像)安装打包,这样就可以避免这个问题
镜像与容器
镜像(image):
docker镜像好比是一个模板,可以通过这个模板来创建容器(最终项目运行是在容器中的)
容器(container):
容器就是一个简易版的Linux
举例:
MySQL01容器:就是一个简易版的Linux系统上安装了一个MySQL
如何避免环境问题
假如你现在有一个Java项目,里面运用了MySQL,Redis,RabbitMQ等技术
那么你把这个项目打包成一个镜像给另一个人
另一个人直接用这个镜像创建一个容器就可以在自己上面运行了,避免环境问题
这相当于直接创建了一个Linux,在Linux上面部署了这些环境,从根源上就帮你把环境配置好了,不需要在本机上配置
总结
Docker是基于go语言开发的
仓库:https://hub.docker.com/(类似GitHub,可以从DockerHub上拉取别人的镜像)
docker的好处:
部署非常块:只需要拉取镜像,生成容器就部署完成,不需要配环境
资源消耗少:其镜像都是精简版,只针对环境部署那部分
docker安装
安装
卸载旧版本的 Docker(如果已安装)
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
docker-ce
安装必要的依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
添加 Docker 的阿里云YUM仓库(官方仓库无法访问的)
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装 Docker CE(社区版)
yum install -y docker-ce docker-ce-cli containerd.io
启动 Docker 服务并设置开机自启
systemctl start docker
systemctl enable docker
验证 Docker 是否安装成功
docker run hello-world
如果看到欢迎消息,说明 Docker 已成功安装。
配置国内镜像加速
为了提高镜像拉取速度,可以配置国内的 Docker 镜像加速器,例如阿里云镜像加速器:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://your_mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
将 your_mirror
替换为实际的加速器地址。
docker常用命令
帮助文档的地址 https://docs.docker.com/reference/
docker images:显示本地镜像
docker images -aq
:-a显示所有镜像,-q只显示镜像iddocker search 镜像名:搜索镜像,目前访问不了docker hub,所以这里无法search到,可以去网站上看
docker pull 镜像名:tag
:拉取镜像,如果不写:tag
那么默认最新版(例如docker pull nginx:1.18.0)
docker rmi -f IMAGE ID
:强制删除镜像,即使有容器存在。但是如果有其他镜像依赖他,则会报错docker rmi IMAGES ID
: 删除镜像,但如果有容器存在则报错docker rmi -f $(docker images -aq):删除所有镜像
docker run [可选参数] image
#参数说明
--name="Name" 容器名字 tomcat01,tomcat02,用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:8080
-P 随机指定端口(大写的P)
#例如
[root@andrew ~]# docker run -it --name centos01 5d0da3dc9764 /bin/bash
# exit退出
exit :容器停止并且退出
Ctrl + P + Q:容器不停止且退出
docker rm 容器id : #删除指定容器,不能删除正在运行的容器
docker rm -f $(docker ps -aq): #删除所有容器
docker start 容器id:启动容器
docker restart 容器id:重启容器
docker stop 容器id:停止当前正在运行的容器
docker kill 容器id:强制停止容器
docker查看日志命令
#-f 指实时更新
#-n 显示几条(默认all)
#-t 显示时间戳
docker logs -tf -n 10 容器id
docker inspect 容器id:查看容器的详细信息
进入容器
#我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
#方式1
docker exec -it 容器id /bin/bash
#方式2
docker attach 容器id
#docker exec 进入容器后开启一个新的终端,可以在里面操作
#docker attach 进入容器正在执行的终端,不会启动新的进程
docker cp 容器id:容器内路径 主机路径
:把容器内的文件拷贝到主机上
[root@andrew home]# docker cp 6864e139dda1:/home/andrew/copytest.txt /home/andrew
Successfully copied 1.54kB to /home/andrew
练习
安装centos
[root@andrew ~]docker pull centos
[root@andrew ~]docker run -it --name centos001 centos
#-it指开启交互,并且开启伪终端
当你运行一个 Docker 容器时,如果不使用 -it
选项,容器可能会立即退出。这是因为容器开启时会执行默认命令,一旦该命令执行完成,容器就会停止运行。
例如,如果你运行一个简单的命令,如 echo "Hello, World!"
,命令执行完成后,容器就会退出,因为它没有更多的工作要做。
CentOS 镜像的默认命令是 /bin/bash
,它会启动一个 Bash shell。如果没有 -it
选项,容器会尝试启动一个非交互式的 Bash shell,但由于没有终端连接,Bash shell 会立即退出,导致容器停止运行。
安装MySQL
[root@andrew ~]docker pull mysql
[root@andrew ~]docker run -e MYSQL_ROOT_PASSWORD=password mysql
#-e MYSQL_ROOT_PASSWORD=password:对于mysql,需要指定root用户的密码才可以成功启动
安装nginx
[root@andrew ~]docker pull nginx
[root@andrew ~]docker run -d --name nginx001 -p 3344:80 nginx
[root@andrew ~]curl localhost:3344
#记得把安全组打开
#通过访问Linux的4433端口即可访问nginx服务(nginx默认端口时80)
为什么docker可以避免环境问题
镜像与容器的
Docker镜像可以理解为一个模板
Docker容器就是基于镜像创建出来的实例
是不是和类与对象很像,但是docker的镜像删除后,容器仍然可以正常使用
如何避免环境问题
每一个docker容器与其他容器是隔离的,与宿主机也是隔离的
docker镜像中已经包含了程序运行的所有依赖
MySQL举例
对于 MySQL 镜像来说,它包含了:
MySQL 数据库软件:包括 MySQL 服务器和客户端工具。
操作系统环境:通常是基于轻量级的操作系统(如 Alpine Linux 或 Debian)。
配置文件:预设的 MySQL 配置文件。
依赖库:运行 MySQL 所需的所有依赖库。
Docker 容器运行时会创建一个独立的运行环境,与宿主机和其他容器隔离。这意味着:
文件系统隔离:容器有自己的文件系统,不会受到宿主机文件系统的影响。
网络隔离:容器有自己的网络接口,通过端口映射与宿主机通信。
当你运行一个包含 MySQL 的 Docker 容器时,容器内的 MySQL 服务会监听某个端口(通常是 3306)。为了从宿主机访问容器内的 MySQL,你需要将容器的端口映射到宿主机的某个端口。例如:
docker run -d -p 3306:3306 --name my-mysql mysql
-p 3306:3306
表示将容器的 3306 端口映射到宿主机的 3306 端口。这样,你就可以通过宿主机的 3306 端口访问容器内的 MySQL 服务了。
commit镜像
将自己的容器打包为一个新的镜像(反过来)
# 命令和git原理类似
# docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -m="mysql原封不动提交" -a="andrew" 64ae9d33dcb7 mysql_commit:001
容器数据卷
问题:如果数据都在容器中,那么删除容器,数据就会丢失
我们需要将容器中的数据存储在本地
我们可以通过卷技术,将容器的目录挂载到本地,实现数据同步
指定路径挂载
[root@andrew home]docker run -it --name centos002 -v /home/test:/home centos /bin/bash
[root@andrew home]docker inspect centos002
匿名挂载
[root@andrew ~]docker run -it --name centos003 -v /home centos
#-v 容器内路径(-v /home)
#匿名挂载中主机的默认挂载目录是 /var/lib/docker/volumes/卷名/_data
具名挂载
[root@andrew volumes]docker run -it --name centos004 -v centos004:/home centos
#-v 卷名:容器内路径
#具名挂载中主机的默认挂载目录是 /var/lib/docker/volumes/卷名/_data
总结
一般使用具名挂载
docker volume ls
#展示所有的卷
[root@andrew volumes]# ll
#在 /var/lib/docker/volumes 目录下ll
docker volume inspect <volume_name>
#来查看卷的具体路径
数据同步
#先绑定本地的
[root@andrew ~]# docker run -it --name centos001 -v centos004:/home centos
[root@andrew ~]# docker run -it --name centos002 --volumes-from centos001 centos
[root@andrew ~]# docker run -it --name centos003 --volumes-from centos002 centos
[root@andrew ~]# docker inspect e855a3d2dbe0(centos3)
"Mounts": [
{
"Type": "volume",
"Name": "centos004",
"Source": "/var/lib/docker/volumes/centos004/_data",
"Destination": "/home",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
]
DockerFile
dockerfile就是构建镜像的脚本
构建步骤:
编写一个dockerfile文件
docker build 构建一个成为一个镜像
docker run运行镜像
docker push发布镜像(Docker hub,阿里云镜像仓库)
基础知识:
关键字都是大写
#为注释
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的,姓名+邮箱
ENV #构建的时候设置环境变量
WORKDIR #镜像的工作目录
RUN #镜像构建的时候需要运行的命令
ADD #步骤,tomcat镜像,这个tomcat压缩包,添加内容
VOLUME #挂载的目录
EXPOSE #指定暴露端口
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候运行的命令,可以追加命令
实战测试
构建一个自己的centos,官方centos里没有vim命令
[root@andrew andrew]# vim dockerfile-cmd-test
FROM centos:7
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 替换默认repo为阿里云repo,避免访问 mirrorlist.centos.org
RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak && \
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && \
yum clean all && yum makecache && \
yum -y install vim net-tools
EXPOSE 80
CMD ["/bin/bash"]
构建
[root@andrew andrew]# docker build -f dockerfile-cmd-test -t cmdtest .
#docker build指构建dockerfile
#-f dockerfile文件名
#-t 构建成的镜像名
#. 构建的上下文路径是当前路径下(一般dockerfile在哪个路径下就写哪个路径)
发布镜像到阿里云
登录阿里云到容器镜像服务创建镜像容器
[root@andrew andrew]docker login --username=aliyun4245954469 crpi-b1uw952vwkztio9k.cn-chengdu.personal.cr.aliyuncs.com
#然后输入密码即可
[root@andrew andrew]docker tag [ImageId] crpi-b1uw952vwkztio9k.cn-chengdu.personal.cr.aliyuncs.com/andrew291/andrew291:[镜像版本号]
#docker tag打标签
#ImageId指当前镜像id
#crpi-b1uw952vwkztio9k.cn-chengdu.personal.cr.aliyuncs.com/andrew291/andrew291:[镜像版本号]指远程镜像名称和版本号
[root@andrew andrew]docker push crpi-b1uw952vwkztio9k.cn-chengdu.personal.cr.aliyuncs.com/andrew291/andrew291:[镜像版本号]
#这里直接push即可
[root@andrew andrew]# docker tag 662628119993 crpi-b1uw952vwkztio9k.cn-chengdu.personal.cr.aliyuncs.com/andrew291/andrew291:1.0
[root@andrew andrew]# docker push crpi-b1uw952vwkztio9k.cn-chengdu.personal.cr.aliyuncs.com/andrew291/andrew291:1.0
docker pull crpi-b1uw952vwkztio9k.cn-chengdu.personal.cr.aliyuncs.com/andrew291/andrew291:[镜像版本号]
怎么找到呢?
登录-镜像容器服务-实例列表-镜像仓库-点击-镜像版本