非原创,根据老师授课内容进行的整理
目录
简介
docker是一个虚拟化平台,官网:Home - Dockerd,诞生于2013年初,基于Google公司的Go语言进行实现。可以通过虚拟化方式,为应用提供可运行的容器,容器之间可以相互隔离,独自运行,基于这种方式我们可以更快打包,部署和运行运行程序,实现软件的快速交付
应用场景
1.应用交付
Docker技术为应用交付领域带来的最大变化就是开发环境的一致性。传统的开发范式需要开发者自己在本地进行开发,但是本地的开发环境和远端的测试和正式环境还是存在差异,所以每次开发完成都需要反复比对环境的差异,包括操作系统以及操作系统里面的一寸软包是否齐全,非常玛麻烦。但是使用Docker镜像,我们可以将所有的环境依赖都打包到镜像中,然后通过镜像来传输,这样会更好的高效。例如,直接在linux系统上安装mysql过程并不简单,需要配置安装源,安装依赖包,对mysql进行配置等,如果要在多台主机上安装,每台主机都要进行这些繁琐的操作,万一服务器挂了,这一系列操作还要再重来一边,但是有了docker,一个安装配置好的mysql容器,可以直接拿到另一台主机上启动,而不必重新安装mysql。同时,还可以保证开发,测试和生产的环境一致。
因为Docker中的容器是相互隔离的,使用相同的镜像就可以保证配置的相同(个人理解)
2.多版本混合部署
随着产品的不断更新迭代,一台服务器上部署同一个应用的多版本再企业内部非常常见。但一个服务器部署同一个软件的多版本,文件路径,端口等资源往往会发生冲突,造成多个版本无法共存的问题。如果用docker,这个问题将非常简单。由于每个容器都有自己独立的文件系统,所有根本不存在文件路径冲突的问题;对于端口冲突问题,只需要再启动容器时指定不同的端口映射即可解决。
3.内部开发测试环境
传统的开发测试环境都是由运维人员进行专门的环境配置而大剑出来的,而且需要运维人员专门维护。环境一旦出现问题,恢复起来也很麻烦。借助与Docker技术,我们将应用程序需要的依赖都固化到Docker镜像中,然后再对应Docker容器中进行开发测试。就算环境出啊先问题,我们只要将当前容器删除重启即可回复
Docker版本说明
Docker分为两个版本,社区版本Docker CE和企业版本Docker EE,企业版由Docker公司支持,可在经过认证的操作系统和云提供商中使用。社区版时免费的Docker产品,包含了完整的Docker平台,不过是由社区进行维护。
Docker核心对象
镜像(Image)
Docker镜像可以堪称是磁盘的特殊的文件系统(Docker Hub),镜像打包了应用的运行环境以及应用程序,是静态的。可以通过Docker启动这个镜像,进而将镜像中的程序在一个容器中启动运行起来。在Docker镜像中,操作系统是高度精简的,镜像中的操作系统还不包含内核,容器中都是共享宿主机的内核。所以有时会说容器仅包含必要的操作系统(通常只有操作系统文件和文件系统对象),容器中查看到的linux内核版本和宿主机一致。可以理解为一个安装程序。
容器(Container)
Docker容器可以将其理解为一个运行镜像的载体,镜像(Image)和容器(Container)的关系,就像是光盘和光驱。容器基于镜像创建、启动,然后运行镜像的中的文件。容器时轻量级的,它不需要管理程序的额外负担,而是直接在主机的内核中运行。我们常常说使用镜像打包应用程序,使用Docker发布,部署应用程序。当你的应用成功在Docker上运行时,这个应用就是容器化应用。我们还可以通过Docker启动的容器堪称时操作系统中的一个进程。
个人理解
镜像就是安装程序,容器就是个运行程序。可以通过镜像创建一个容器。
Docker应用架构分析
架构图
Docker是一种Client/Server(CS)架构的应用程序,Docker客户端与Docker守护进程进行对话,该守护进程完成构建,运行和分发Docker容器的繁重工作。Docker客户端和守护程序可以在同一系统上运行,或者您可以将Docker客户端连接到远程Docker守护程序。参考docker官网Docker overview | Docker Documentation
- Docker Client是安装完成Docker之后,直接使用的docker命令。
- Docker Host就是我们安装了docker的宿主机(就是安装了docker的操作系统)
- Docker Daemon是docker的后台守护进程,侦听并处理Docker客户端命令,管理Docker对象,例如镜像,容器,网络和卷(数据卷)。
- Registry是docker拉取镜像的远程仓库,提供大量的镜像供下载,下载完成之后保存在Images(本地仓库)中。相当于一个大型的软件商店
- Images是Docker本地的镜像仓库,可以通过docker images查看镜像文件
Docker运行机制
docker pull
- 客户端将指令发送给docker deamon(客户端将指令发送给守护进程)【用户告诉小艾我要下载一个东西】
- 守护进程docker daemon先检查本地仓库(images)中有没有相关的镜像【小艾先看看本地有没有安装包】
- 如果本地没有相关的镜像,则向镜像服务器请求,将远程镜像下载到本地【小艾如果在本地没有发现安装包,则从应用商店下载应用】
docker run
- 检查本地是否存在指定镜像,如果不存在就从共有仓库下载【小艾打开安装包,没有安装包先去应用商店下载】
- 利用镜像创建并启动一个容器【使用安装包安装应用程序】
- 分配一个文件系统(简版linux系统),并在只读的镜像层外挂在一层可读写层【安装了一个虚拟手机,本来没有修改权限,然后给自己加个外挂,让自己可以修改】(这个感觉没有那么理解)
- 从宿主机配置的网桥接口中桥接一个虚拟接口到容器中去【虚拟机可以使用主机的网络】
- 从地址池配置一个ip地址给容器
- 执行用户指定的应用程序【执行app】
安装虚拟机【跳过】自行下载
离线安装Docker系统(重点)
详见老师地址:
https://yutian.blog.csdn.net/article/details/119705377
第一步:下载docker离线包
https://download.docker.com/linux/static/stable/x86_64/docker-20.10.6.tgz
其他版本:
https://download.docker.com/linux/static/stable/
第二步:下载离线安装工具
https://github.com/Jrohy/docker-install/
第三步:将下载好的资源放在一个目录
第四步:在linux环境下,创建/root/setup/docker目录,然后拷贝下载好的资源到此目录(可以通过modexterm工具直接上传至linux目录)
第五步:执行安装操作
1.进入安装程序所在文件夹
cd /root/setup/docker
2.为install.sh添加执行权限
chmod +x install.sh
3.安装docker
./install.sh -f docker-20.10.6.tgz
第六步:安装成功异构,检查安装状态
docker info
在线安装详见老师文档
Docker服务基本操作
查看Docker状态:查看docker是否启动了,是否是运行状态
systemctl status docker
看到绿色active(running)就是正在运行
停止docker服务
systemctl stop docker
启动docker服务
systemctl start docker
设置Docker开机自启
systemctl enable docker
禁用Docker开机自启
systemctl disable docker
重启Docker服务
systemctl restart docker
查看Docker信息
docker info
查看docker info 中具体key的信息,例如:
docker info | grep 'Docker Root Dir'
Docker镜像加速
由于国内网络问题,需要配置加速器来加速,通过修改配置文件/etc/docker/deamon.json
通过命令直接生成文件 daemon.json(没有回通过<<EOF >自动创建)
cat <<EOF > /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com"
],
"max-concurrent-downloads": 10,
"log-driver": "json-file",
"log-level": "warn",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"data-root": "/var/lib/docker"
}
EOF
需要确保登录的用户为管理员root,设置好以后重启docker服务
Docker镜像操作实践
下载镜像
语法:docker pull 镜像名称
docker pull hello-world
浏览镜像文件
docker images
查看镜像详情
语法:docker inspect 镜像名称或者镜像id
docker inspect hello-world
查看镜像历史
一个镜像是由多个层(layer)组成的,那么,我们要如何知道各个层的具体内容呢?通过docker history命令,可以列出各个层(layer)的创建信息,例如:
docker history hello-world
导出镜像文件
镜像导出(Linux系统中的镜像在下到本地),方便导出给他人使用
docker save hello-world | gzip > hello-world.tar.gz
删除镜像
语法:docker image rm 镜像名或镜像id 删除容器不需要加image,删除镜像时一定要添加image
dockeer image rm hello-world
导入镜像
需要在镜像压缩包文件目录下执行
docker load < hello-world.tar.gz
运行镜像文件
docker run hello-world
Docker数据管理实践‘
概述:
在容器中管理数据主要有两种方式:
- 数据卷(Voolumes)
- 挂载主机目录(Bind mounts)
数据卷
数据卷时一个可供一个或多个容器使用的特殊目录,可以在容器之间共享和重用,默认会一直存在,即使容器被删除【类似网盘,文件在容器中使用,数据卷也同步进行更新,即使容器被删除,数据卷不会被删除】
数据卷操作
第一步:创建数据卷
container-vol为自己起的名字
docker volume create container-vol
第二步:查看所有数据
docker volume ls
查看指定数据卷的信息
docker volume inspect container-vol
查询结果:
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/container-vol/_data", 宿主机默认存放数据卷位置
"Name": "container-vol",
"Options": {},
"Scope": "local"
}
]
第三步:启动挂载数据卷的容器,例如:
docker run -it --mount source=container-vol,target=/root centos:7 bash
run 启动容器
-it -i是需要进行交互,-t是分配终端
--mount 挂载命令
bash 类似命令行
简写:
docker run -it -v container-vol:/root centos:7 bash
-v container-vol:/root 把数据卷container-vol挂载到容器的/root目录
第四步:删除数据卷(如果数据卷被容器使用则无法删除)
docker volume rm container-vol
清理无主数据卷
docker volume prune
挂载主机目录
我们还可以再主启动容器时,以目录直接挂载的方式进行数据操作,
docker run -it -v /usr/app:/opt/app centos:7 bash
冒号左边表示宿主机中的位置
冒号右边的位置是容器中的位置
-v用于指定挂载目录,如果本地目录(宿主机目录)不存在,Docker会自动为你按照挂载目录进行目录创建
查看挂载目录信息
docker inspect 容器id
Docker镜像制作实践
背景
我们基于docker pull指令可以从远程仓库下载我们需要的一些镜像(image)但是镜像仓库中的镜像是从哪里来的呢,假如镜像仓库中没有我们需要的镜像呢。
镜像制作过程
我们可以将一些文件通过Dockerfile文件进行描述,然后通过build操作构建一个镜像
其中Dockerfile用来构建镜像的文本文件,内部会包含一条条构建镜像所需的指令和说明
制作JDK镜像
准备工作
- centos7镜像(所有的镜像文件创建时都需要有一个空的centos镜像,就类似通过一个空的光盘或者u盘创建一个系统启动盘是一样的)【创建镜像时需要准备依赖】
- jdk压缩包jdk-8u51-linux-x64 tar.gz(可以从课前资料获取),基于此压缩包,制作jdk镜像
创建Dockerfile文件
在创建新的镜像时都需要有一个Dockerfile文件(文件名一定要注意大小写),这个文件中定义镜像制作过程,
第一步:进入jdk-8u51-linux-x64.tar.gz文件所在目录,基于vim创建Dockerfile文件
vim Dockerfile
说明,这里一定要注意文件的大小写
第二步:按键盘上的“i”进入编辑模式
第三步:拷贝如下代码到你的Dockerfile中,例如
FROM centos:7
ADD jdk-8u51-linux-x64.tar.gz /usr/local/docker
ENV JAVA_HOME=/usr/local/docker/jdk1.8.0_51 \
PATH=/usr/local/docker/jdk1.8.0_51/bin:$PATH
CMD ['bash']
第四步:拷贝完成,按ESC进入命令行模式
第五步:然后输入:wq保存退出
创建JDK镜像文件
在Dockerfile所在目录执行docker build指令 例如:
docker bulid -t jdk:8 . 不要丢.点表示当前目录-t表示镜像表示(镜像名),是tag单词的缩写
基于JDK镜像启动sentinel
https://yutian.blog.csdn.net/article/details/119223262
需要准备jdk、sentinel
Docker安装mysql
第一步:找到官方镜像(hub.docker.com)/使用本地镜像,通过load进行安装【第一步第二步二者选其一即可】
第二部:拉取指定版本的mysql,也可以指定拉取版本【如果不指定版本默认下载的是最新版】
docker pull mysql:8.0.23
第三步:检查mysql镜像
docker images
第四步:启动运行mysql镜像(docker run)
sudo docker run -p 3306:3306 --name mysql \
-v /usr/local/docker/mysql/mysql-files:/var/lib/mysql-files \
-v /usr/local/docker/mysql/conf:/etc/mysql \
-v /usr/local/docker/mysql/logs:/var/log/mysql \
-v /usr/local/docker/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:8.0.23
sudo 表示以管理员权限运行(可以不加)
\ 代表换行(前面需要添加空格)
第五步:查看是否安装成功
docker ps
第六步:进入容器
docker exec -it mysql bash
第七步:进入mysql
mysql -uroot -proot
导入数据库文件
第一步:在宿主机位置添加sql脚本
随便选择一个都可以,进入到指定位置,例如:
cd /usr/local/docker/mysql/mysql-files/
然后将文件复制进宿主机的目录
第二步:进入mysql容器执行脚本
docker exec -it mysql bash
source /var/lib/mysql-files/文件名
第三步:查看数据库
show databases;
停止和启动mysql服务(可选)
停止
docker stop mysql
启动
docker start mysql
设置开机自启
docker update mysql --restart=always
安装Redis数据库
redis学习:https://blog.csdn.net/maitian_2008/category_11166577.html?spm=1001.2014.3001.5482
安装步骤
第一步:下载镜像文件/解压镜像
docker pull redis
第二步:准备配置文件
创建redis配置文件目录
mkdir -p /usr/local/docker/redis01/conf
在配置文件目录下创建redis.conf配置文件(这个文件一定要创建,否则在我们进行目录挂载时默认生成的时一个目录)
创建配置文件
touch /usr/local/docker/redis01/conf/redis.conf
第三步:创建redis实例并启动
sudo docker run -p 6379:6379 --name redis01 \
-v /usr/local/docker/redis01/data:/data \
-v /usr/local/docker/redis01/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf
第四步:查看正在运行的进程
docker ps
访问redis服务器
第一步:控制台直接连接redis测试
docker exec -it redis01 bash
第二步:检测redis版本
redis-server -v
或者
redis-cli -v
第三步:登录redis(默认不需要密码)
redis-cli
或着直接使用
docker exec -it redis01 redis-cli
停止和启动redis服务
停止
docker stop redis01
启动
docker start redis01
重启
docker restart redis01
安装Nginx
安装步骤
第一步:拉取nginx镜像(或者从本地load)
docker pull nginx
第二步:查看images镜像
docker images
第三步:创建数据卷(也可以使用以前创建的数据卷)
docker volume create nginx-vol
查看数据卷对应的宿主机目录
docker inspect nginx-vol
第四步:启动nginx服务
docker run --name nginx -p 80:80 -v nginx-vol:/etc/nginx -d nginx
/etc/nginx为nginx镜像文件默认的解压目录
如果需要修改nginx配置,可以直接去nginx-vol数据卷对应的目录去修改
访问nginx服务
在linux的浏览器中输入localhost/在windows系统中输入虚拟机的ip地址,80端口可以不写(面试考点:http协议的默认端口就是为80,https默认端口为443)
停止和启动nginx服务
停止
docker stop nginx
启动
docker start nginx
重启
docker restart nginx
安装Nacos组件
安装步骤
第一步:拉取nacos或者Load
docker pull nacos/nacos-server:1.4.1
第二步:mysql中执行nacos的sql脚本
1)将此文件nacos-mysql.sql(可以从code服务器下载)拷贝到mysql容器的宿主机对应的挂载目录(氪通过docker inspect mysql 查看具体的挂载目录)
2)在linux环境下启动并登录mysql
进入mysql容器(前提是mysql已启动)
docker exec -it mysql bash
登录mysql
mysql -uroot -proot
3)通过source指令运行容器目录下的sql文件(注意选择自己存放宿主机对应位置执行,否则执行不到文件)
source /ect/mysql/nacos-mysql.sql
第三步:创建并启动nacos容器(需要根据自己的ip,端口,密码进行更改)
docker run \
-e TZ="Asia/Shanghai" \
-e MODE=standalone \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_DATABASE_NUM=1 \
-e MYSQL_SERVICE_HOST=192.168.126.128 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=root \
-e MYSQL_SERVICE_DB_NAME=nacos_config \
-p 8848:8848 \
--name nacos \
--restart=always \
-d nacos/nacos-server:1.4.1
参数说明
- 单节点模式
MODE=standalone
- 数据库地址
MYSQL_SERVICE_HOST
- 数据库用户名
MYSQL_SERVICE_PASSWORD
- 需连接的数据库名称
MYSQL_SERVICE_DB_NAME
- 端口映射
-p 8848:8848
任意时候重启容器,开机就能自动启动容器(需要设置Docker为开机自启)
--restart=always
第四步:检查nacos服务
docker ps
如果启动失败可以查看启动日志
docker container logs nacos
nacos启动日志位置/home/nacos/logs/start.out文件中
访问nacos服务
我使用本机ip访问不到,查看日志使用日志生成的地址可以访问到,如果有知道的大佬还请帮忙解答一下
Docker容器互联
简介
Docker中存在多个容器时,容器与容器之间经常需要进行通讯,例如nacos访问mysql,redis集群中各个节点之间的通讯。
解决方案
Docker中容器与容器之间进行通讯的解决方案一般有两种:
两个容器通过宿主机进行通讯(容器中的端口回映射到宿主机上)
两个容器之间通过虚拟网络进行连接,但是需要我们在docker中创建网络
初始化网络
架构设计
新建网络
docker network create -d bridge t-net
t-net为自己起的名字
-d driver网络类型 默认bridge
说明,创建好这个网络后,在网络上添加容器,容器就可以通讯了
查看网络信息
列出所有网络
docker network ls
查看网络信息
docker inspect 网络id
实现容器互联
创建容器
创建第一个容器
docker run -it --name app1 --network t-net centos:7
创建第二个容器
docker run -it --name app2 --network t-net centos:7
测试网络互通
ping app1/ping app2