栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Docker学习笔记—基础篇

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Docker学习笔记—基础篇

Docker Docker的架构

Docker的概念解析 Docker的Run步骤

Docker为什么比虚拟机快

docker比虚拟机有更少的抽象层

docker利用的是宿主机的内核,避免引导。

安装Docker

安装需求

  • To install Docker Engine, you need a maintained version of CentOS 7 or 8. Archived versions aren’t supported or tested.

卸载旧版本

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

仓库安装Docker

安装工具包

yum install -y yum-utils

设置镜像仓库

yum-config-manager 
    --add-repo 
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo  #默认是国外,慢

yum更新

yum makecache fast

安装Docker最新的客户端、服务,容器

yum install docker-ce docker-ce-cli containerd.io

启动Docker

systemctl start docker

验证是否启动成功

docker version

运行Hello World程序

docker run hello-world

docker run hello-world 运行分析

查看下载的Hello-World镜像

docker images

Docker卸载

yum remove docker-ce docker-ce-cli containerd.io
 rm -rf /var/lib/docker
 rm -rf /var/lib/containerd

阿里云镜像加速

#前提,需要阿里云账号登录阿里云 这里懒得注册账号了,就没做了
Docker的常用命令

帮助命令

docker version #docker版本显示
docker info #docker系统信息显示,包括镜像和容器的数量
docker 命令 --help #帮助命令

官方文档命令查询

https://docs.docker.com/engine/reference/run/

镜像命令

# 查看本机所有的镜像
docker images

# 只显示镜像的ID
docker -images -q

# 搜索dockerHub上的镜像
docker search xxx [--filter=stars=xxx] #--filter 过滤器

#下载镜像
docker pull xxx[:tag] #tag:版本

#删除指定镜像
docker rmi -f 镜像名称或者镜像ID

#批量删除所有镜像
docker rmi -f $(docker images -aq)

容器命令

  • 有了镜像才能创建容器

新建容器并启动

docker run [可选参数] image
#可选参数
--name="xxx"  #启动的容器的名称
-d			  #后台运行
-it	 	 	  #交互方式运行,进入容器查看内容
-p			  #指定容器的端口
-P 		 	  #随机指定端口

退出容器

exit  #容器停止退出
#容器中使用 ctrl+P+Q 快捷键来实现容器不停止退出

列出所有正在运行的容器

docker ps [可选参数]
-a   #列出当前运行的容器和历史运行过的容器
-n=? #显示最近创建的容器
-q	 #只显示容器的编号

删除容器

#删除指定容器,不能删除正在运行的容器
docker rm 容器ID

#删除指定容器
docker rm -f 容器ID

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

启动和停止容器

docker start 容器ID 	#启动指定的容器
docker restart 容器ID #重启指定的容器
docker stop 容器ID   #停止指定的容器
docker kill 容器ID 	 #强制停止当前运行的容器

常用的其它命令

#后台运行
docker run -d 镜像名
#查看容器中的进程命令
dokcer top 容器ID

查看容器的元数据

docker inspect 容器ID

进入当前正在运行的容器

#方式1,进入容器后打开一个新的终端,可以操作
docker exec -it 容器ID /bin/bash

#方式2,进入容器正在执行的终端
docker attach 容器ID

从容器内拷贝文件到主机上

docker cp 容器ID:容器内路径 目的主机路径

内存使用查看

docker stats

ES限制内存启动

#es不限制内存启动时,对于内存比较小的宿主机来说,有可能造成卡死,所以有时候需要限制内存消耗启动
docker run -d --name es01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch

#参数解析
-d #后台启动
--name es01 #容器别名
-p 9200:9200 -p 9300:9300 #端口映射 主机端口:Docker容器内端口
-e "discovery.type=single-node" #集群配置,此处单节点
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" #限制内存消耗,最小64M,最大512M
镜像管理可视化面板
  • portainer
#Docker的图形化界面管理工具
docker run -d -p 8088:9000 
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • Rancher(CI/CD),进阶使用
commit镜像
docker commit 提交成为一个新的副本

docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[tag]
容器的数据卷

容器内的数据通过挂载到容器外的文件夹来同步数据

容器的持久化和同步操作!容器间也是可以数据共享的

使用数据卷

使用命令来挂载 -v

docker run -it -v 主机目录:容器内的目录[:ro/rw]
#可选参数解析
ro : 路径只读 	#容器有权限,不可更改内容,只能在宿主机更改文件
rw : 路径可读可写
#查看容器的详细信息
docker inspect 容器ID
具名挂载&匿名挂载

匿名挂载:挂载时只写了容器内的路径,没有写容器外的路径

#匿名挂载宿主机的卷名是一串数字字符组合的长字符串
-v 容器内路径

#查看所有的卷(volume)的情况
docker volume ls

具名挂载:挂载时未写容器外的路径,而是使用 卷名:容器内的路径格式

#具名挂载可以方便我们找到卷
-v 卷名:容器内路径

所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/***目录下

#三种挂载的区别
-v /宿主机路径:容器内的路径    #指定路径挂载
-v 卷名:容器内的路径		  #具名挂载
-v 容器内的路径			   #匿名挂载

#拓展 
可以使用dockerfile来在构建容器时自动挂载
数据卷容器

多个容器之间进行数据挂载同步时,父容器就是数据卷容器

-- volumes-from

#示例
docker run 新容器 --volumes-from 已经启动的容器 镜像id/镜像名[:tag]

#多个容器进行数据挂载同步,当删除其中一个容器时,与其相关的数据不会丢失,其它容器会同步保存相关文件数据。只有当挂载的所有容器都被删除时,才会丢失数据。一旦容器和宿主机之间挂载同步,只有容器全部被删除,宿主机数据删除或者删除宿主机时数据才会丢失
DockerFile

Dockerfile就是用来构建docker镜像的脚本文件

构建步骤:

  • 编写一个dockerfile文件
  • docker bulid构建成为一个镜像
  • docker run 运行镜像
  • docker push 发布镜像(DockerHub)
dockerfile构建过程

基础语法

  1. 每个保留的关键字(指令)都必须是大写字母
  2. 执行从上往下执行
  3. #表示注释
  4. 每一个指令都会创建提交一个新的镜像层,并提交

dockerfile指令

FROM		#基础镜像,一切从这里开始的构建
 	#镜像是谁写的,标准命名:姓名+邮箱
RUN			#镜像构建时需要需要运行的命令
ADD			#添加如Tomcat,MySQL等内容
WORKDIR		#镜像的工作目录
VOLUME		#挂载卷的目录
EXPOSE		#暴露端口 [-p]命令
CMD			#指定这个容器启动时需要运行的命令,只有最后一个会生效,可被替代 
ENTRYPOINT	#指定这个容器启动时需要运行的命令
onBUILD		#当构建一个被继承DockerFile,这个时候就会运行ONBUILD指令
COPY		#将我们的文件拷贝到镜像中
ENV			#构建的时候设置环境变量
#查看镜像构建的历史记录
docker histroy 镜像ID
Docker实战1 Tomcat镜像制作
  1. 准备一个tomcat、jdk的压缩包
  2. 编写readme.txt和dockerfile等文件
#dockerfile文件
FROM centos
MMAINTAINER ycy
COPY readme.txt /usr/local/readme.txt

ADD jdk-8u221-linux-x64.rpm /usr/local/
ADD apache-tomcat-9.0.54.tar.gz /usr/local/

RUN yum -y install vim

ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.54
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.54
ENV PATH $PATH:$CATALINA_HOME/lib;$CATALINA_HOME/bin

EXPOSE 8080
 
CMD /usr/local/apache-tomcat-9.0.54/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.54/bin/logs/catalina.out
  1. 构建镜像
docker build [-f] -t 镜像名 .
#以Dockerfile命名时,[-f]参数可不写
  1. 启动镜像
docker run
-d
-p 9090:8080
--name tomcat01
-v /home/ycy/build/tomcat/test:/usr/local/apache-tomcat-9.0.54/webapps/test
-v /home/ycy/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.54/logs diytomcat
发布镜像

DockerHub

#登录docker账户
docker login -u [账户名]

docker push [作者/镜像名:tag]
#错误解决
The push refers to repository [docker.io/ycy/diytomcat]
An image does not exist locally with the tag: ycy/diytomcat

#给镜像加一个tag
docker tag [镜像id] [新的镜像名称:版本号]

阿里云镜像 这里同样懒得注册阿里云账号,没做了

  1. 登录阿里云
  2. 找到容器镜像服务
  3. 创建命名空间
  4. 创建容器镜像(镜像仓库)
  5. 有推送镜像教程
Docker网络 什么是Docker0

安装docker即会安装docker0,启动时展示,是一个虚拟网卡

#实验:使用Tomcat容器来连接数据库容器,实现容器间的网络互通

#启动一个tomcat 
docker run -d -P --name tomcat01 tomcat

#查看容器的内部网络地址
docker exec -it 容器名 ip addr
#错误
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ifconfig": executable file not found in $PATH: unknown

#解决方法:
#进入容器内
apt update && apt install -y iproute2

#Linux内ping容器地址
ping 172.17.0.2 			#状态:OK

原理

  • 只要安装了docker,就会安装一个网卡docker0,以桥接模式接到真实的网络上
  • 每启动一个容器,都会被docker0分配一个地址
  • docker 网络使用evth-pair技术来保证网络互通
docker网络—evth-pair技术

当没有容器启动时,我们在Linux中使用ip addr命令查看ip地址信息,只有本机回环地址、本机网络地址,和docker0地址信息

当我们启动一个容器时查看ip地址信息

此处多了一个51: veth61199a7@if50的网卡信息

进入容器内部查看ip地址信息

容器内也有一个50: eth0@if51的网卡信息

再启动一个tomcat容器,查看ip地址信息

发现又多了一个53: veth8635c73@if52的网卡信息

进入新的容器内查看ip信息

容器内也有一个52: eth0@if53的网卡信息

解释

51: veth61199a7@if50和50: eth0@if51、53: veth8635c73@if52和52: eth0@if53这两对网卡信息就是evth-pair技术的实现。在docker网络中,使用evth-pair技术来实现网络的互通

  • evth-pair 就是一对的虚拟设备接口,它们都是成对出现的,一端连着协议,一端彼此相连
  • 我们一般使用evth-pair充当一个桥梁,来实现docker通信,以上述的实例,画图理解

小结

docker中的所有网络接口都是虚拟的,因为虚拟的接口转发效率高。

但是只要容器停止或者删除了,对应的网桥和docker0分配的地址就失效了,再次启动时会分配新的一对evth-pair接口和网络地址。

思考:微服务场景中,使用JDBC连接数据库时,通常需要设置database url = ip ,如果容器崩了或者停止了,就会导致ip改变,JDBC无法连接MySQL,如何解决?

解决:使用容器的ID或者服务名来连接通信,而不是使用ip来连接。通过服务名来进行容器的访问,docker解决方案为 --link

docker网络— --link
# 启动两个tomcat,使用tomcat1来ping测试tomcat2
docker exec -it tomcat1 ping tomcat2
# 状态 False 无法找到tomcat2服务
ping: tomcat2: Name or service not known

# --link示范
#再启动一个tomcat3,以--link的形式和tomcat2连接启动
docker run -d -P --name tomcat3 --link tomcat2 tomcat
# tomcat3 ping tomcat2 
docker exec -it tomcat3 ping tomcat2
# 状态 Ok
PING tomcat2 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat2 (172.17.0.2): icmp_seq=1 ttl=64 time=0.169 ms
64 bytes from tomcat2 (172.17.0.2): icmp_seq=2 ttl=64 time=0.082 ms
......
# tomcat2 ping tomcat3 
docker exec -it tomcat2 ping tomcat3
# 状态 False
ping: tomcat3: Name or service not known

# 结论:使用--link命令后,tomcat3可以ping通tomcat2,但是tomcat2不可以ping通tomcat3
# 原理探究
# 查看tomcat3的hosts文件,可以发现标注绿色的一行做了地址 容器名称的绑定,所以tomcat3可以ping通tomcat2
docker exec -it tomcat3 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.17.0.2	tomcat2 1bdb7bc92c17`
172.17.0.4	b4240695272c



# 错误
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ping": executable file not found in $PATH: unknown

# 解决
# 进入容器
apt-get update
apt install iputils-ping

注意:–link已经不推荐使用,而使用自定义网络

docker网络— 自定义网络

容器互联一般指自定义网络实现,虽然使用–link也能实现,但是不够灵活

# 查看所有的docker网络
docker network ls

# 网络模式
* bridge 	 : 桥接模式      docker0与自定义网络
* none	 	 : 不配置网络	一般不用
* host	 	 : 主机模式		 和宿主机共享网络
* contairner : 容器网络联通	用的很少(局限性很大) 资料需自查
# 测试:创建一个自定义网络

# 之前从镜像直接启动容器时,会默认走docker0,[]内参数默认会添加,例如如下命令
docker run -d -P --name tomcat1 [--net bridge] tomcat
# docker0特点:默认,域名不能访问,虽然可以通过--link打通,但是不够灵活
 
# 自定义一个网络 
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 ynet

# 参数解释
--driver bridge			 :指定桥接模式
--subnet 192.168.0.0/16	 :指定网段
--gateway 192.168.0.1	 :指定网关
ynet 					 :自定义网络名

# 再次查看所有网络信息
docker network ls

# 指定网络启动两个tomcat
docker run -d -P --name tomcat1 --net ynet tomcat
docker run -d -P --name tomcat2 --net ynet tomcat

# 使用容器名ping测试
docker exec -it tomcat1 ping tomcat2
# 状态 OK

由此得出,使用自定义网络时,不需要任何配置,docker为我们维护好了关系,同一个网段下容器可以通过容器名互联,而且搭建集群时,不同的集群使用不同的网络,互相不影响

docker网络— 不同网段容器互联

案例:以上已经有了在ynet网段下的两个容器,并且可以ping通,如果使用默认的docker0再创建一个tomcat3,tomcat3是否能和tomcat1和tomcat2联通?

# 使用默认的docker0来创建一个tomcat3容器
docker run -d -P --name tomcat3 tomcat

# 使用tomcat3来ping测试tomcat1、tomcat2
docker exec -it tomcat3 ping tomcat2
docker exec -it tomcat3 ping tomcat1

# 状态 False
ping: tomcat2: Name or service not known
ping: tomcat1: Name or service not known

# 原因:tomcat3和tomcat2、tomcat1不在同一个网段,自然不通
# 解决:
# 通过 docker network --help 命令以发现有 connect 参数

# 使用connect参数来完成不同网段的容器的互联互通
docker network connect ynet tomcat3

# 使用tomcat3来ping测试tomcat1、tomcat2
docker exec -it tomcat3 ping tomcat2
docker exec -it tomcat3 ping tomcat1

#状态:OK

#原理:

  • 通过docker network inspect ynet命令可以看到以上信息中,ynet直接给tomcat3分配了一个本网段的地址
  • 其本质是一个容器两个地址

取消互联可以使用disconnect参数,如
docker network disconnect ynet tomcat3

课程链接

https://www.bilibili.com/video/BV1og4y1q7M4?spm_id_from=333.999.0.0

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/338588.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号