学习笔记尚硅谷周阳老师的Docker教程学习笔记

Posted 棉花糖灬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习笔记尚硅谷周阳老师的Docker教程学习笔记相关的知识,希望对你有一定的参考价值。

本文是尚硅谷周阳老师的Docker教程的相关学习笔记,暂时还没有检查勘误过。

一、Docker简介

1. 简介

Docker的出现是为了解决代码在本机可以正常运行,而部署到其他机器不能运行的问题。这是因为代码运行所需要的环境、系统、配置、数据等不同,Docker透过镜像将程序运行所需要的系统环境由下而上打包,达到应用程序跨平台间的无缝接轨运行。

Linux 容器技术的出现就解决了这样一个问题,而 Docker 就是在它的基础上发展过来的。将应用运行在 Docker 容器上面,而 Docker 容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作。

2. Docker与传统虚拟化方式的不同

  • 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程
  • 而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便
  • 每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源

3. Docker三要素

docker三要素:镜像、仓库、容器

镜像就是模板,容器就是镜像的一个实例,docker利用容器独立运行一个或一组应用,可以把容器看作是一个简易版的Linux环境和运行在其中的应用程序,仓库是集中存放镜像的地方。

4. Docker的安装

(1) centOS安装docker

yum install -y epel-release
yum install -y docker-io
# 安装后的配置文件:/etc/sysconfig/docker
service docker start # 启动docker后台服务
docker version # 查看版本,验证是否安装成功

(2) ubuntu安装docker

curl -sSL https://get.daocloud.io/docker | sh

安装教程可查看:https://docs.docker.com/engine/install/ubuntu/

(3) 配置阿里云镜像加速器:

首先在阿里云平台注册账户,登录后找到“镜像加速器”选项,在相应的操作系统下的命令复制,命令大约长下面这样。注意,其中https那段我没有给出完整的链接。

sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://*.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload

sudo systemctl restart docker

ps -ef|grep docker:查看是否是阿里云加速器

解决docker权限问题:

sudo gpasswd -a username docker #将普通用户username加入到docker组
newgrp docker #更新docker组

(4) 测试

  • docker run hello-world:运行hello world

运行镜像的流程

二、Docker常用命令

1. docker帮助命令

(1) 查看docker版本

  • docker version:查看版本信息

(2) 查看docker信息

  • docker info:查看docker信息

(3) docker帮助命令

  • docker --help:帮助命令

2. docker镜像命令

(1) 列出所有镜像

  • docker images:列出本地主机上的镜像,镜像由镜像名:tag唯一标记,tag可认为是版本号
    • docker images -a:列出本地所有的镜像(含中间映像层)
    • docker images -q:只显示镜像的id
    • docker images --digests:显示镜像的摘要信息
    • docker images --no-trunc:显示完整的镜像信息

选项说明:

  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

(2) 在github搜索镜像

  • docker search 镜像名:在github上搜索某个镜像
    • docker search -s 30 tomcat:列出starts数不小于30的镜像
    • docker search --no-trunc 镜像名:显示完整的镜像描述
    • docker --automated 镜像名:只列出automated build类型的镜像

(3) 下载镜像

  • docker pull 镜像名:下载镜像
    • docker pull 镜像名:TAG:下载指定TAG的镜像,不加TAG默认为latest

(4) 删除未在使用的镜像

  • docker rmi 镜像名:删除未在使用镜像,若在使用则不能删除,默认删除latest的
    • docker rmi -f 镜像名:强制删除
    • docker rmi -f 镜像名1:TAG 镜像名2:TAG:删除多个
    • docker rmi -f $(docker images -qa):删除全部

3. docker容器命令

以CentOS镜像为例演示,先用docker pull centos命令下载相应镜像

(1) 新建并启动容器

  • docker run [options] 镜像名 [command] [arg...]:新建并启动容器

  • docker run --name=容器新名字:为容器指定一个名称

    • docker run -i 镜像名:以交互模式运行容器,通常与-t同时使用
  • docker run -t 镜像名:为容器重新分配一个伪输入终端,通常与-i同时使用

    • docker run -d 镜像名:后台运行容器,并返回容器id,即启动守护式容器
    • docker run -P 镜像名: 随机端口映射
    • docker run -p 镜像名: 指定端口映射,有以下四种格式
      • ip:hostPort:containerPort
      • ip::containerPort
      • hostPort:containerPort
      • containerPort

(2) 列出正在运行的容器

  • docker ps:列出当前所有正在运行的容器

(3) 列出历史上运行过的容器

  • docker ps -a:列出当前所有正在运行的容器+历史上运行过的容器
    • docker ps -l:显示最近创建的容器
    • docker ps -n 数字:显示最近创建的n个容器
    • docker ps -q:静默模式,只显示容器编号
    • docker ps --no-trunc:不截断输出

(4) 退出容器

  • exit:容器停止退出
  • Ctrl+P+Q:容器不停止退出

(5) 启动/重启/停止容器

  • docker start 容器名:启动容器

  • docker restart 容器名:重启容器

  • docker stop 容器名:停止容器,类似于电脑关机

  • docker kill 容器名:强制停止,类似于电脑拔电源关机

(6) 删除容器

  • docker rm 容器名:删除已停止的容器,若未停止则不删除
  • docker rm -f 容器名:停止并删除容器
    • docker rm -f $(docker ps -aq):删除所有容器

(7) 后台运行容器

  • docker run -d 容器名:启动守护式容器,运行在后台,用docker ps查看看不到,因为已经退出了。docker容器后台运行,必须有一个前台进程

(8) 容器日志相关

  • docker logs [options] 容器名:查看容器日志

  • docker logs -t 容器名:加入时间戳

    • docker logs -f 容器名:跟随最新的日志打印(动态打印)
    • docker logs --tail 数字 容器名:显示最后多少条

(9) 查看容器内的进程

  • docker top 容器名:查看容器内的进程

(10) 查看容器内部细节

  • docker inspect 容器名:查看容器内部细节,返回是json串

(11) 进入正在运行的容器并以命令行交互

  • docker exec -it 容器名 bash命令:在容器中打开新的终端,并可以启动新的进程
    • docker exec -it 容器名 ls -l /tmp:不进入容器,直接拿到ls -l /tmp命令的执行结果,等价于使用docker exec -it 容器名 /bin/bash先进入bash,再执行ls -l /tmp得到结果
  • docker attach 容器名:直接进入容器启动命令的终端,不会启动新的进程

(12) 拷贝容器内容到本机

  • docker cp 容器名:容器中文件的路径 本机路径:从容器内拷贝文件到本机上

三、Docker镜像

1. 联合文件系统(UnionFS)

UnionFS是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,UnionFS是docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统该,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

2. docker镜像加载原理

docker的镜像实际上是由一层层的文件系统组成,这种层级的文件系统就是UnionFS

bootfs(boot文件系统)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动的时候会加载bootfs文件系统,在docker镜像的最底层是bootfs。这一层与Linux系统该是一样的,包含boot加载器和内核。当boot加载完成后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs(root文件系统),在bootfs之上,包含的是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统该发行版,如Ubuntu、CentOS等。

对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就行了。所以对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用bootfs。

3. 镜像的特点和优点

(1) 镜像的特点

docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作“容器层”,“容器层”之下的为“镜像层”。

(2) 分层镜像的优点

使用分层镜像的优点是可以共享资源,比如有多个镜像都从相同的base镜像构建而来,那么宿主机上只需要保存一份base镜像,内存中也只需要加载一份base镜像,就可以为所有容器服务了。镜像的每一层都可以被共享。 以pull为例,在下载的过程中可以看到docker的镜像好像是在一层一层的在下载。

4. 镜像提交

(1) commit命令

  • docker commit -m="提交的描述信息" -a="作者" 容器名 要创建的目标镜像名:[TAG]:提交容器副本使之成为一个新的镜像

(2) 镜像提交实例

  • docker run -it -p 8080:8080 tomcat:从hub上下载tomcat镜像到本地并运行

  • 故意删除上一步镜像生产tomcat容器的文档

  • docker commit -a="zuzhiang" -m="del tomcat docs" 容器名 atguigu/tomcat/02:1.2:以它为模板提交一个没有文档的tomcat新镜像atguigu/tomcat02

  • docker run -it -p 7777:8080 atguigu/tomcat02:1.2:启动新镜像并访问localhost:7777/docs界面,可以发现与原镜像相比无文档

四、容器数据卷

1. 容器数据卷

(1) 是什么

容器删除后数据自然也就没有了,所以用卷来保存数据。容器数据卷功能是持久化和数据共享。 卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File Syste提供一些用于持续存储或共享数据的特性。

(2) 容器数据卷的特点

  • 数据卷可以在容器之间共享或重用数据
  • 卷中的更改可以直接生效
  • 数据卷中的更改不会包含在镜像的更新中
  • 数据卷的生命周期一直持续到没有容器使用它为止

2. 容器内添加数据卷

(1) 直接命令添加

  • docker run -it -v /宿主机绝对路径:/容器内目录[:ro] 镜像名 .:将宿主机的目录和容器内目录绑定,之后对宿主机或容器内相应文件夹的内容添加和修改就是同步的了。容器每次启动后会将数据同步。添加:ro时表示是只读模式,宿主机可以添加和修改文件,但是容器内不可以。

  • docker inspect 容器名:查看数据卷是否挂载成功,其中Volumes里面有绑定的目录

  • 容器和宿主机之间数据共享

  • 容器停止后,宿主机修改数据是否同步

如果无权限,则使用docker run -it -v /宿主机绝对路径:/容器内目录 --privileged=true 镜像名 .即可

(2) dockerFile添加

dockerFile是镜像的描述文件

  • 根目录下新建mydocker文件夹并进入

  • VOLUME["/dataVolumeContainer","/dataVolumeContainer2","/dataVolumeContainer3"]:可在dockerFile中能使用volume指令来给镜像添加一个或多个数据卷

  • vi dockerfile:File构建

    FROM centos
    VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
    CMD echo "finished,--------success1"
    CMD /bin/bash
    
  • docker build -f /mydocker/dockerfile -t zza/centos:build后生成镜像,获得一个新镜像zza/centos

  • docker run -it zza/centos:运行容器,容器内自带两个容器数据卷,对应的宿主机的目录默认,可以通过docker inspect查看

3. 数据卷容器

(1) 是什么

命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。

(2) 容器间传递共享

  • 先启动一个父容器:docker run -it --name dc01 zza/centos

  • dc02继承自dc01:docker run -it --name dc02 --volumes-from dc01 zza/centos

  • 回到dc01可以看到02/03各自添加的都能共享了

  • 删除dc01,dc02修改后dc03可否访问

  • 删除dc02后dc03可否访问

  • 新建dc04继承dc03后再删除dc03

  • 结论:

    • 父子容器之间数据共享,删除父容器后,修改某一子容器会响应其兄弟元素
    • 容器之间配置信息的传递,数据卷生命周期一直持续到没有容器使用它为止

五、DockerFile解析

1. DockerFile

(1) 是什么

dockerFile是用来构建docker镜像的构建文件,是由一系列命令和参数构成的脚本。 Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等

(2) 构建三步骤

  • 编写DockerFile文件

  • docker build

  • docker run

(3) DockerFile内容基础知识

  • 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
  • 指令从上到下顺序执行
  • #表示注释
  • 每条指令都会创建一个新的镜像层,并对镜像进行提交

(4) docker运行dockerFile的大致流程:

  • docker从基础镜像运行一个容器
  • 执行一条指令并对容器做出修改
  • 执行类似docker commit的操作提交一个新的镜像层
  • docker再基于刚提交的镜像运行一个新容器
  • 执行dockerFile中的下一条指令知道所有指令都执行完成

2. 保留字指令

  • FROM:基础镜像,当前镜像是基于哪个镜像的

  • MAINTAINER:镜像维护者的姓名和邮箱地址

  • RUN:容器构建时需要运行的命令

  • EXPOSE:当前容器对外暴露出的端口

  • WORKDIR:指定在创建容器后,终端默认登录进来的工作目录

  • ENV:用来在构建镜像过程中设置环境变量

  • ADD:将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包

  • COPY:类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源文件>的文件/目录复制到镜像内的<目标路径>位置

  • VOLUME:容器数据卷,用于数据保存和持久化工作

  • CMD:指定一个容器启动时要运行的命令,DockerFile中可以有多个CMD命令,但只有最后一个生效,CMD会被docker run之后的参数替换

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lVvPW0WL-1622124381817)(https://z3.ax1x.com/2021/05/26/29BUxg.png)]

  • ENTRYPOINT:指定一个容器启动时要运行的命令,ENTRYPOINT的目的和CMD一样,都是指定容器启动程序及参数

  • ONBUILD:当构建一个被继承的DockerFile时运行命令,父镜像在被子镜像继承后父镜像的onbuild被触发

3. 案例

(1) 自定义镜像mycentos

编写

  • 默认CentOS镜像的情况

    29B0qs.png

  • 编写DokerFile文件

    FROM centos
    MAINTAINER zuzhiang<zuzhiang@126.com>
    
    ENV MYPATH /tmp
    WORKDIR $MYPATH
    RUN yum -y install vim
    RUN yum -y install net-tools
    
    EXPOSE 80
    
    CMD echo $MYPATH
    CMD echo "success    ok"
    CMD /bin/bash
    

构建

  • docker build -t mycentos:1.3

29BDZn.png

运行

  • docker run -it mycentos:1.3

镜像变更历史

  • docker history 镜像名:列出镜像变更历史

(2) CMD/ENTRYPOINT镜像案例

相同点

都是指定一个容器启动时要运行的命令

CMD

DockerFile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换。在tomcat容器dockerFile的最后一行是CMD ["catalina.sh","run"],但如果docker run -it tomcat ls -l时,则命令行参数会把最后一行CMD命令给替换,导致tomcat不能正常启动

CMD版查询IP信息的容器

FROM centos
RUN yum install -y curl
# curl命令可以用来执行下载、发送各种HTTP请求,指定HTTP头部等操作
# 执行后,www.baidu.com的html就会显示在屏幕上了
CMD ["curl","-s","http://ip.cn"]

docker build -f dockerfile4 -t myip:构建

ENTRYPOINT

docker run之后的参数会被当作参数传递给ENTRYPOINT,之后形成新的命令组合

ENTRYPOINT版查询IP信息的容器

FROM centos
RUN yum install -y curl
ENTRYPOINT ["curl","-s","http://ip.cn"]
# 被继承时,直接在子dockerFile中"FROM 容器名"进行继承
ONBUILD RUN echo "father images onbuild."

先build自己镜像myip,然后运行docker run -it myip -i,变成了执行curl -s -i http://ip.cn命令

29BNRS.png

(3) 自定义镜像Tomcat9

  • 创建工作目录:mkdir -p /mydockerfile/tomcat9

  • 新建txt文件:touch c.txt

  • 将jdk和tomcat安装的压缩包拷贝到新建的目录

    • cp /jdk-8u171-linux-x64.tar.gz
    • cp /opt/apache-tomcat-9.0.8.tar.gz
  • 新建DockerFile文件:vim Dockerfile

    FROM centos
    MAINTAINER zuzhiang<zuzhiang@126.com>
    # 把宿主机当前上下文的c.txt靠背巾容器/usr/local/路径下
    COPY c.txt /usr/local/cincontainer.txt
    # 把javahetomcat添加到容器内
    ADD jdk-8u171-linux-x64.tar.gz /usr/local
    ADD apache-tomcat-9.0.8.tar.gz
    # 安装vim编辑器
    RUN yum -y install vim
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    # 配置java和tomcat环境变量
    ENV JAVA_HOME /usr/local/jdk1.8.0_171
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8
    ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    # 容器运行时的监听的端口
    ENVEXPOSE 8080
    # ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh"]
    # CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]
    CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out
    
    
  • 构建:docker build -t zzatomcat9 .

  • 运行:docker run -d -p 9080:8080 --name myt9 -v /mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test -v /mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.8/logs --privileged=true zzatomcat9

  • 验证:在浏览器访问localhost:9080

(4) 综合前面的tomcat容器卷将测试的web服务test发布

  • 总体概述

    # 在mydockerfile/tomcat9/test下
    mkdir WEB-INF
    cd WEB-INF
    vim web.xml
    cd ..
    vim a.jsp
    
    
  • web.xml内容

    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    
      xmlns="http://java.sun.com/xml/ns/javaee"
    
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    
      id="WebApp_ID" version="2.5">
    
      
    
      <display-name>test</display-name>
    
     
    
    </web-app>
    
    
  • a.jsp内容

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN" "http://www.23.org/TR/html/loose.dtd">
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            <title>Insert title here</title>
        </head>
        <body>
            -------------------welcome------------------
            <%="I am in docker tomcat self"%>
            <br>
            <br>
            <% System.out.println("=============docker tomcat self");%>
        </body>
    </html>
    
    
  • 测试:在浏览器访问localhost:9080/test/a.jsp

4. 小总结

六、Docker常用安装

1. 安装tomcat

  • docker search tomcat :docker hub上面查找tomcat镜像

  • docker pull tomcat:从docker hub上拉取tomcat镜像到本地

  • docker images:查看你是否有拉取到tomcat

  • docker run -it -p 8080:8080 tomcat:运行镜像

2. 安装mysql

docker search mysql # docker hub上面查找mysql镜像
docker pull mysql:5.6 # 从docker hub上拉取mysql:5.6镜像到本地
docker images # 查看你是否有拉取到mysql
# 运行镜像
docker run -p 12345:3306 --name mysql -v /zza/mysql/conf:/etc/mysql/conf.d -v /zza/mysql/logs:/logs -v /zza/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6

3. 安装redis

docker search redis # docker hub上面查找redis镜像
docker pull redis:3.2 # 从docker hub上拉取redis:3.2镜像到本地
docker images # 查看你是否有拉取到redis
# 运行镜像
docker run -p 6379:6379 -v /zza/myredis/data:/data -v /zza/myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf -d redis:3.2 redis-server /usr/local/etc/redis/redis.conf --appendonly yes
# 在/zza/myredis/conf/redis.conf目录下新建redis.conf文件
vim /zza/myredis/conf/redis.conf/redis.conf
# 添加redis配置文件
# 进入reids并添加键值对
docker exec -it redis容器id redis-cli

七、本地镜像推送到阿里云

docker run -it 镜像
docker -a zuzhiang -m "new mycentos 1.4 from 1.3" 镜像id 新镜像名
# 在阿里云开发者平台创建仓库镜像
# 将镜像推送到registry
docker --username= registry.cn-hangzhou.aliyuncs.com
docker tag 镜像id registry.cn-hangzhou.aliyuncs.com/zuzhiang/centos.1.4
docker push registry.cn-hangzhou.aliyuncs.com/zuzhiang/centos.1.4
# 在https://dev.aliyun.com查找
docker pull registry.cn-hangzhou.aliyuncs.com/zuzhiang/centos.1.4

以上是关于学习笔记尚硅谷周阳老师的Docker教程学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

尚硅谷Vue系列教程学习笔记

尚硅谷Vue系列教程学习笔记

尚硅谷Vue系列教程学习笔记

尚硅谷Vue系列教程学习笔记

尚硅谷Vue系列教程学习笔记

尚硅谷Vue系列教程学习笔记