Docker简单入门

前言

1、什么是docker?

  • 是一个C/S架构的承载应用运行的平台软件

2、为什么用docker

  • 解决应用运行环境配置的复杂性
  • 轻量级,内存占用低
  • 扩容方便,使用镜像部署效率高,只需要将程序及其所依赖的环境打包成镜像,即可在服务器上将程序及其运行环境一站式部署

3、docker与虚拟机之间的区别

4、docker核心架构

  • 镜像:一个镜像代表一个应用环境,他是一个只读的文件,如mysql镜像,tomcat镜像,nginx镜像等
  • 容器:镜像每次运行之后就是产生一个容器,就是正在运行的镜像,特点就是可读可写
  • 仓库:用来存放镜像的位置,类似于maven仓库,也是镜像下载和上传的位置
  • dockerFile:docker生成镜像配置文件,用来书写自定义镜像的一些配置
  • tar:一个对镜像打包的文件,日后可以还原成镜像

5、docker镜像原理

镜像是什么?

镜像是一种轻量级的,能够独立执行的软件包,用来打包软件运行环境和基于运行环境开发的软件,包含软件运行所需要的所有内容,包括代码,库,环境变量以及配置文件。

  • UnionFS(联合文件系统):
  				Union文件系统是一种分层,轻量级并具高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。这种文件系统特性:就是一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

镜像原理

  • docker的镜像实际是由一层一层的文件系统组成

    • bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。在docker镜像的最底层就是bootfs这一层与Linux/Unix系统是一样的,包含boot加载器(bootloader)和内核(kernel)。当boot加载完后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时会卸载bootfs。
    • rootfs(root file system),在bootfs之上,包含的就是典型的linux系统中的/dev,/proc,/bin,/etc等标准的目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu/CentOS等等。
    • 我们平时安装进虚拟机的centos都有1到几个GB,为什么docker这里才200MB?对于一个精简的os,rootfs可以很小,只需要包括最基本的命令,工具,和程序库就可以了,因为底层直接使用Host的Kernal,自己只需要提供rootfs就行了。由此可见不同的linux发行版,他们的bootfs是一致的,rootfs会有差别。因此不同的发行版可以共用bootfs。
  • 为什么docker镜像要采用这种分层结构呢?

    • 最大的一个好处就是资源共享
    • 比如:有多个镜像都是从相同的base镜像构建而来的,那么宿主机只需在磁盘中保存一份base镜像。同时内存中也只需要加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。Docker镜像都是只读的。当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称为容器层,容器层之下都叫镜像层。

安装

Docker官网 下载链接 官方文档 练习play-with-docker

方式一

# 安装docker依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 配置yum依赖设置docker的yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装最新版的docker
yum install -y docker-ce docker-ce-cli containelrd.io
# 启动docker
systemctl start docker
systemctl enable docker
# 关闭docker
systemctl stop docker
# 测试docker安装
docker run hello-world
# 安装过程中 docker中报错 failure: repodata/repomd.xml from mirrors.aliyun.com_docker-ce_linux_centos_docker-ce.pro
  解决方案
  https://blog.csdn.net/qq_18948359/article/details/102715729

指定安装版本

yum list docker-ce --showduplicates | sort -r

sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd. io

sudo yum install docker-ce-18.09.5-3.e17 docker-ce-cli-18.09.5-3.e17 containerd.io

方式二

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

配置

1、阿里云镜像仓库

2、配置阿里云加速

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://uz579bhl.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

3、验证配置

 docker info
# 出现以下信息则配置成功
     Insecure Registries:
      127.0.0.0/8
     Registry Mirrors:
      https://uz579bhl.mirror.aliyuncs.com/
     Live Restore Enabled: false

卸载已存在的Docker

sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine

卸载方式二:
https://blog.csdn.net/m0_67390379/article/details/123731952

常用命令

服务命令

# 查看版本
docker version

# 查看详细信息
docker info

# 指令帮助
docker --help

# 启动|停止|重启|状态查询
systemctl start|stop|restart|status docker

镜像命令

# 查看所有镜像
docker images

# 搜索镜像
docker search 镜像名称

# 下载镜像
docker pull 镜像名[:TAG|@DIGEST]

# 上传镜像
docker push 镜像名称

# 备份镜像
docker save 镜像 -o xxx.tar

# 加载备份的镜像
docker load -i xxx.tar

# 查看镜像的制作历史
docker history 镜像

# 检查镜像的详细参数信息
docker inspect 镜像

# 给镜像改名字及tag标签
docker tag 镜像 名称

# 删除镜像
docker rmi 镜像		# 删除
docker rmi -f 镜像	# 强制删除

# 删除所有镜像
docker rmi -f $(docker images -qa)

# 删除所有没打标签的镜像
docker rmi -f $(docker images -q | awk '/^<none>/ { print $3 }')

# 删除所有包含关键字的镜像
docker rmi --force [-f] $(docker images | grep 尽量准确的关键字 | awk '{print $3}')

# 显示所有虚镜像
docker image ls -f dangling=true

# 删除REPOSITORY、TAG为none的镜像(虚悬镜像)
docker rmi $(docker images -q -f dangling=true)

容器命令

基本命令(容器外直接执行)

# 运行一个容器
docker run --help
# 例如
docker run -it --name myNginx -p 80:80 nginx
docker run -d --name myNginx -P nginx

# 查看容器
docker ps --help
docker ps -a

# 停止|关闭|重启容器
docker start 容器
docker restart 容器
docker stop 容器
docker kill 容器

# 查看容器内进程
docker top 容器
# 查看容器内部细节
docker inspect

# 查看容器的运行日志
docker logs [OPTIONS] 容器
-f			查看实时日志
--tail		查看后10条日志

# 删除一个容器
docker rm -f 容器

# 删除所有状态为 Exited 的容器
docker rm $(docker ps -qf status=exited)

# 删除所有容器
docker rm -f $(docker ps -aq)

容器内数据交互命令

# 1.在宿主机发送命令到容器内部执行
docker exec -it 容器 命令
-i # 以交互模式运行容器,通常与-t一起使用
-t # 分配一个伪终端

# 进入容器内部
# 注意:这里要理解bash,sh这些终端其实也是命令(等同于ls,pwd等等),只是导致的结果是进入了终端
docker exec -it 容器 命令(bash/sh...) 
# 以root用户发送命令到容器内部并执行
docker exec -it -u root 容器 命令(bash/sh...)

# 2.容器内安装软件(前提是在容器的bash里执行)
apt-get update
apt-get install 安装包

# 3.退出容器
exit

# 4.将容器打包为新的镜像
docker commit -a "作者名称" -m "描述信息" 容器ID 目标镜像名称:TAG

# 5.上传文件到容器
docker cp 宿主机文件绝对路径 容器:容器路径

# 6.从容器下载文件到宿主机
docker cp 容器:容器内文件绝对路径 宿主机路径

# 7.检查容器详细参数
docker inspect 容器
	
# 7.设置容器和宿主机共享目录(数据卷valueme)
docker run -it -v /宿主机文件/文件夹绝对路径:/容器内绝对路径:ro(只读)  镜像
# 例如:docker run -d --name "nginx" -p 80:80 -v /root/test/:/usr/share/nginx/html:ro nginx
# docker inspect nginx
"Mounts" : [
    {
        "Type": "bind",
        "Source": "/root/test", // 宿主机绝对路径
        "Destination": "/usr/share/nginx/html", // 容器内绝对路径
        "Mode": "ro", // only read 只读
        "RW": false,
        "Propagation": "rprivate"
    }
]

Docker中安装常用软件

☆docker可视化工具Portainer部署与汉化

# 1、搜索镜像
docker search portainer
# 2、下载最高start
docker pull portainer/portainer
# 3、部署单机版仅本机能访问,命令如下
docker run -d -p 9000:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data --name prtainer portainer/portainer

下载portainer汉化包 (提取码:6vjr)

# 解压
tar -xvf public.tar
# 将public移动到根目录
mv public /
# 部署汉化版portainer
docker run -d -p 9000:9000 --restart=always  -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data -v /public:/public --name prtainer-test  portainer/portainer

安装mysql数据库

# 1、安装mysql
docker pull mysql:TAG
# 2、启动mysql
docker run --name mysql -e MYSQL_ROOT_PASSWORD="root用户的密码" -d -p 3306:3306 mysql:TAG

可能出现的问题

官方参考

# 3.进入mysq1容器
docker exec -it mysql bash

# 4.查看mysq1日志
docker logs -f mysql

# 5.使用自定义配置参数
docker run --name mysql -v /root/mysql/conf.d:/etc/mysq1/conf.d -e MYSQL_ROOT_PASSWORD=root -d mysq1:TAG

# 6.将容器数据位置与宿主机位置挂载保证数据安全
docker run --name mysql -p 3306:3306 -d -v /root/mysq1/data:/var/lib/mysql 
-v /root/mysq1/conf.d:/etc/mysq1/conf.d -e MYSQL_PASSWOT_PASSWORD=root mysql:TAG

# 7.访问测试

# 8.数据备份
# 导出全部数据
docker exec mysql sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/sql.sql
# 导出指定库的数据
docker exec mysql sh -c 'exec mysqldump --databases 库表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/sql.sql
# 导出指定库数据不要
docker exec mysql sh -c 'exec mysqldump --no-data --databases 库表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql
# 9.执行sq1文件到mysq1中
docker exec -i mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' <  /root/sql.sq1

安装redis服务

# 1、搜索镜像
docker search redis
# 2、拉取下载
docker pull redis:TAG
# 3、启动
docker -d -p 3306:3306 --name redis redis:TAG
# 4、查看启动日志
docker logs -f redis
# 5、进入容易内部操作
docker exec -it redis /bin/bash

# 6.挂载外部自定义配置启动redis容器
# 默认情况下redis官方镜像中没有redis.conf配置文件需要去官网下载指定版本的配置文件
	# 6.1 wgethttp://download.redis.io/releases/redis-5.0.8.tar.gz下载官方安装包
	# 6.2 将官方安装包中配置文件进行复制到宿主机指定目录中如/root/redis/redis.conf文件
	# 6.3 修改需要自定义的配置
	# bind0.0.0.0开启远程权限
	# 默认是rdb持久化模式
	# appenonly yes开启aof持久化,每秒同步一次
docker run -v /root/myredis/conf:/usr/local/etc/redis --name redis -d -p 6379:6379 redis redis-server /usr/local/etc/redis/redis.conf  

# 7.将数据目录挂载宿主机保证数据安全
docker run --name redis -v /root/redis/data:/data -v /root/myredis/conf:/usr/local/etc/redis -d -p 6379:6379 redis redis-server /usr/local/etc/redis/redis.conf

springboot中使用redis

1、引入操作redis依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、通过上述导入的依赖提供的RedisTemplete(操作对象)或者StringRedisTemplete(主要操作字符串)操作redis数据库,使用了模板方法设计模式。

3、application.xml配置redis数据库,主机、端口、数据库

4、注意点

  • RedisTemplete持久化对象时,目标对象需实现序列化接口
  • 设置键的序列化方式为Stirng的方式
  • 值的序列化方式一般设置为json序列化

安装tomcat应用服务器

# 搜索镜像
docker search
# 拉取镜像
docker pull tomcat:tag
# 以用完即删的方式运行
docker run --rm 
# 挂载tomcat的webapps目录到宿主机中运行
docker run --rm -d -p 8888:8080 -v /root/tomcat/webapps:/usr/local/tomcat/webapps tomcat:9.0

安装Mongo

  • 注意身份验证的问题

安装ElasticSearch分布式搜索引擎

  • 拉取镜像
  • 配置linux虚拟机:配置JVM
  • 启动ElasticSearch
  • 安装IK分词器
  • 安装Kibana

Docker与集群管理工具Swarm

引言

Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。

DockerFile

什么是DockerFile?

  • 是Docker镜像的描述文件,是有一系列命令及参数构成的脚本,用来自定义镜像的构建文件。

DockerFile保留指令集

构建第一个DockerFile

# 1、创建DockerFile
echo "FROM nginx" > Dockerfile
echo "RUN echo 你好RUN" >> Dockerfile
echo "CMD echo 你好CMD" >> Dockerfile
# 2、构建
docker build -t 镜像[:tag] .
# 3、查看
docker images
docker inspect 镜像[:tag]

指令语法

FROM

  • 基于哪个镜像进行构建新的镜像,构建时都会自动从docker hub拉取base镜像作为Dockerfile的第一个指令出现
FROM <image>
FROM <image>[:<tag>] 		使用版本不写为latest

RUN

  • RUN指令将在当前映像之上的新层中执行任何命令并提交结果。生成的提交映像将用于Dockerfile中的下一步
  • 语法:
RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN echo hello
RUN ["executable","param1","param2"](exec form)
RUN ["/bin/bash","-c","echo hello"] # 指定bash执行命令
RUN yum install vim
RUN ["yum","install","vim"]

EXPOSE (重要:外部与容器通信的通道)

  • 用来指定构建的镜像在运行为容器时对外暴露的端口
EXPOSE 80/tcp  # 不则默认使用tcp
EXPOSE 80/udp

CMD

  • 用来为启动的容器指定执行的命令,注意:在Dockerfile中只能有一条CMD指令。如果列出多个命令,则只有最后一个命令才会生效。
CMD ["executable","param1","param2"](exec form, this is the preferred form)
CMD ["param1","param2"](as default parameters to ENTRYPOINT)
CMD command param1 param2(shell form)

WORKDIR

  • 用来为Dockerfile中的任何RUN、CMD、ENTRYPOINT、COPY和ADD指令设置工作目录。如果WORKDIR不存在,即使它没有在任何后续Dockerfile指令中使用,它也将被创建。
WORKDIR /path/to/workdir
WORKDIR /a
WORKDIR b
WORKDIR C
# 注意:WORKDIR指令可以在Dockerfile中多次使用。如果提供了相对路径,则该路径将与先前WORKDIR指令的路径相对

ENV

  • 用来为构建镜像设置环境变量。这个值将出现在构建阶段中所有后续指令的环境中。
ENV <key> <value>

ADD (支持通配符)

  • 用来从context上下文复制新文件、目录或远程文件url,并将它们添加到位于指定路径的映像文件系统中。
ADD hom* /mydir/ 					# 通配符添加多个文件
ADD hom?.txt /mydir/				# 通配符添加
ADD test.txt relativeDir/			# 可以指定相对路径
ADD test.txt /absoluteDir/			# 也可以指定绝对路径
ADD url

COPY命令

  • 用来将context目录中指定文件复制到镜像的指定目录中
COPY src dest
COPY ["<src>", ... "<dest>"]

VOLUME命令

  • 用来定义容器运行时可以挂在到宿主机的目录,如果构建的时候没写,则不允许任何容器内数据被挂载
VOLUME ["/data"]

Dockerfile构建springboot项目部署

  • 找一个能正常运行的springboot项目,使用maven的打包工具达成jar包

  • 将可运行的jar包上传到服务器中

  • 在Dockerfile中构建jar包的运行环境

    • 在服务器中编写Dockerfile

    • FROM openjdk:8
      WORKDIR /jar_run
      ADD test.jar /jar_run
      EXPOSE 8989
      ENTRYPOINT ["java","-jar"]
      CMD ["test.jar"]
      
  • 构建镜像

    • docker build 名称[:tag] .
  • 运行镜像

    • docker run -d -p 8989:8989 --name test test:lastes
    • 注意:原项目中数据库连接地址url由localhost变更为指定路径,容器与容器之间是隔离的,使用localhost访问不到彼此之间的容器。
    • 解决方案:可以尝试把mysql构建在springboot程序运行环境中一同构建成为自定义镜像,避免更改所有数据库连接地址
  • 访问项目

查看docker容器IP

参考:https://blog.csdn.net/web18224617243/article/details/126327598

  • docker
# 获取某个容器ip
docker -it 容器 cat /etc/hosts
docket inspect 容器
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 容器

# 获取所有容器ip
docker inspect -f '{{.Name}} - {{.NetworkSettings.IPAddress }}' $(docker ps -aq)
  • 使用docker-compose获取容器ip
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
  • 用户脚本

经验:可以考虑在 ~/.bashrc 中写一个 bash 函数:

cd && vim .bashrc

docker_ip() {
	sudo docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $1
}
dockeriplist() {
	sudo docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
}

source .bashrc

测试脚本

# 查看指定容器ip
docker_ip <容器>
# 查看所有容器ip
dockeriplist
posted @ 2021-03-09 21:49  黄河大道东  阅读(99)  评论(0编辑  收藏  举报