• Docker初识笔记


    Docker

      docker说白了就是:环境打包

    我们能用docker什么?

      1.如果配置好本地的linux环境交接给其他人,很麻烦,交接时要告诉他,装这个装那个,还可能出现问题,那我直接把这个环境放到docker中打包成镜像给他,原来的环境怎么样的还是怎么样,我们不能去纠结配置环境的问题,而留下更多的时间来解决其他问题

      2.虚拟化技术,很多就用了docker把一些已经装好的资源分配给云用户,让用户购买他们的服务等

    帮助文档  

      文档:http://www.dockerinfo.net/document

    docker三大要素

      镜像:模板(类似于'类')

      容器:镜像的实例(类似于'对象')

      仓库:存放镜像文件的地方,可能在云,可能在注册服务器上,最大的公开仓库是docker hub,国内阿里云就够用了

    docker本身是一个容器运行载体,我们把我们要的配置程序和依赖包形成一个可以交付的运行环境,把这个环境打包成为一个image镜像文件,只有通过这个镜像文件才能生成docker容器,image文件可以看做容器的模板,docker根据image文件生成容器的实例,同一个image文件,可以生成多个同时运行的容器实例

    安装:使用 yum 安装(CentOS 7下)

      目前docker要求centos7环境达到64位,系统内核版本3.10以上

    cat /etc/redhat-release #查看linux内核版本
    sudo yum remove docker 
                      docker-client 
                      docker-client-latest 
                      docker-common 
                      docker-latest 
                      docker-latest-logrotate 
                      docker-logrotate 
                      docker-selinux 
                      docker-engine-selinux 
                      docker-engine
    #移除之前版本
    
    sudo yum install -y yum-utils device-mapper-persistent-data lvm2
    #安装一些必要的系统工具
    
    sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    #添加软件源信息
    
    sudo yum makecache fast
    #更新 yum 缓存
    
    sudo yum -y install docker-ce
    #安装 Docker-ce
    
    sudo systemctl start docker
    #启动 Docker 后台服务

    docker version
    #查看docker版本

    docker的基本使用:

    创建一个容器并执行命令

    docker pull ubuntu:15.10  #拉取官方的乌版图
    docker run ubuntu:15.10 /bin/echo "Hello world" #docker执行docker的二进制文件 #run 结合docker一起使用,表示运行一个容器 #ubuntu:15.10指定要运行的镜像,Docker首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像 #/bin/echo "Hello world": 在启动的容器里执行的命令

    运行交互式容器命令

    docker run -i -t ubuntu:15.10 /bin/bash
    #-i -t -t:在新容器内指定一个伪终端或终端。 -i:允许你对容器内的标准输入 (STDIN) 进行交互。

       运行exit命令或者使用CTRL+D

    启动容器(后台模式)

    docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
    #返回bf8e12e0315d51a7fb8ee2cc2b788f13b1a651aadbb9194e6ff74825fade3d0a,这个长字符串叫做容器ID,由64位组成,对每个容器来说都是唯一的,我们可以通过容器ID来查看对应的容器发生了什么 
    docker ps ↓

    CONTAINER ID:容器ID    NAMES:自动分配的容器名称

    docker logs CONTAINER_ID /或者 NAME 命令,查看容器内的标准输出

    docker logs amazing_cori
    docker logs -f amazing_cori    #,-f参数可以像tail -f xxx.log一样输出
    docker logs tail 3 amazing_cori  #查看倒数三行并持续输出

    docker帮助命令

    docker ps --help 查看docker ps的帮助
    docker info #查看主机个人信息

    查看容器

    
    docker ps -a #查看所有容器
    docker ps -l #查看最后一次创建的容器
    docker ps   #查看正在使用的容器
    docker ps -s #查看正在使用的容器,增加参数容器大小 

    停止容器

    docker stop amazing_cori

    启动容器

    docker start amazing_cori

    运行容器实例

    docker pull training/webapp #载入镜像,载入步骤,docker先回去local本地找你输入的镜像名称,如果没有则去你设置的镜像仓库pull拉去
    docker run -d -P training/webapp python app.py
    #-d 后台运行 -P将容器内部使用的网络端口映射到我们使用的主机上

      运行127.0.0.1:32768显示hello world!

    查看dockor端口

      dockor port 容器名
    
      #或者可以加端口号docker port 容器名 5000 

    查看应用程序配置信息

    docker inspect 9ac    #查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息

    创建容器

    #该命令与run命令一样,但唯一区别是只是创建,不启动
    docker create [OPTIONS] IMAGE [COMMAND] [ARG...] docker create
    --name myrunoob nginx:1.3

    kill命令

    docker kill [OPTIONS] CONTAINER [CONTAINER...]
    docker kill -s KILL nginx    #杀掉nginx     -s为向容器发送的信号

    top命令

    docker top 容器名称    #返回容器中的ps -ef 操作

     

    移除容器

    删除容器时,容器必须是停止状态,否则会报错,除非加-f

    docker rm xxx
    docker rm -f xxx  #强制删除
    docker rm -f xxx01 xxx02 #删除多个
    docker rm -f $(docker images -qa)  #删除所有容器

    pause/unpause命令

    docker pause :暂停容器中所有的进程。
    
    docker unpause :恢复容器中所有的进程。

    docker的镜像

      当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载

    列出本机docker的所有镜像源

    [root@rainbol ~]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    hello-world         latest              fce289e99eb9        6 months ago        1.84kB
    ubuntu              15.10               9b9cb95443b5        3 years ago         137MB
    training/webapp     latest              6fae60ef3446        4 years ago         349MB
    • REPOSITORY:表示镜像的仓库源

    • TAG:镜像的标签,指定不同的镜像标签对应不同的仓库源版本,如果在docker run时不指定镜像仓库源的版本,默认latest最后版本 

    • IMAGE ID:镜像ID

    • CREATED:镜像创建时间

    • SIZE:镜像大小

    docker images  -a  #列出本地所有镜像,含中间镜像层

              -q   #只显示当前镜像的IMAGE ID

              -qa   #列出本机所有镜像的IMAGE iD 可以做批处理操作,如删除

    获取下载镜像  下载完成后就可以使用了

    docker pull ubuntu:13.10
    docker pull tomcat:7

    查看镜像源

    docker search httpd
    docker search -s 1000 httpd  #查看点赞数超过1000的httpd源

    删除镜像

    docker rm images [images id]
    docker rmi [images id]    #rm images 和 rmi 是一样的
    docker rmi -f [images id]   #强制删除

    docker镜像原理

      docker镜像基于联合文件系统组成,一层套一层的结构,比如我们要下载tomcat,原理是不同发行版本共用linux内核(rootfs).这是底层,之后下载精简版centos->之后下载jdk->最后才下载tomcat,所以说这一层一层的结构组成了tomcat,镜像删除后会留在主机缓存,第二次安装会比第一次快

    端口映射

    docker run -d -p 5000:5000 training/webapp python app.py
    -p : 是容器内部端口绑定到指定的主机端口。左5000是实际服务器端口,右5000是容器5000端口
    
    docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py    也可以指定ip
    
    
    docker run -d -P training/webapp python app.py
    -P 是容器内部端口随机映射到主机的高端口
    
    默认都是绑定 tcp 端口,如果要绑定 UDP 端口,可以在端口后面加上 /udp

    如何进入一个已经创建了的容器

    进入Docker容器比较常见的几种做法如下:

    • 使用docker attach
    • 使用SSH
    • 使用nsenter
    • 使用exec

    1.首次创建进入容器时,让/bin/bash可用

    docker run -i -t -d ubuntu:15.10 /bin/bash    #-d表示后台运行/bin/bash
    docker attach xxx  #进入容器,xxx为容器id,直接进入容器启动命令的终端,不会启动新的进程

      当多个窗口同时使用该命令进入该容器时,所有的窗口都会同步显示。如果有一个窗口阻塞了,那么其他窗口也无法再进行操作

    2.使用SSH进入Docker容器(不推荐)

    3.nsenter进入容器

    $ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz  
    $ tar -xzvf util-linux-2.24.tar.gz  
    $ cd util-linux-2.24/  
    $ ./configure --without-ncurses  
    $ make nsenter  
    $ sudo cp nsenter /usr/local/bin 

    docker ps
    sudo docker inspect -f {{.State.Pid}} xxx   #xxx为容器id拿到PID为1234

    sudo nsenter --target 1234 --mount --uts --ipc --net --pid  #把PID为1234放进入就就可以进入容器了

    4. exec命令  在容器中打开命令的终端,不会启动新的进程

    docker ps    #拿到容器id为xxxxx
    docker exec -it xxxxx /bin/bash  #-it的意义就是开启交互终端的意思
    docker exec -it xxxxx ls  #执行或者查看结果指令,会返回给我们,但是不会进入容器内

      

    退出容器

    exit

    docker安装nginx

    #nginx的简单部署
    docker pull nginx #安装nginx源 docker run
    --name nginx_test -P -d nginx #创建并运行nginx
    nginx自定义部署
    mkdir -p ~/nginx/www ~/nginx/logs ~/nginx/conf #首先在目录建立nginx目录
    
    docker run -d -p 8082:80 --name runoob-nginx-test-web -v ~/nginx/www:/usr/share/nginx/html -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v ~/nginx/logs:/var/log/nginx nginx
    #-v为创建挂载,将本地的文件加载到容器中,需指定位置

    文件下载与下载

    docker cp 容器id:容器文件路径 宿主机路径  #从容器中下载到主机
    dockor cp 宿主机路径 容器id:容器路径    #主机上传到容器

    docker镜像加速

    我们经常发现连接国外的镜像下载很慢,那就使用国内厂商的镜像加速,这里推荐阿里云镜像加速器,登陆阿里云账号后搜索容器镜像服务->镜像加速器->centos->到本机中如linux  $vi /etc/docker/daemon.json (如果没有的话就新建,默认就是没有的) -> 添加 {
      "registry-mirrors": ["https://cz6ionug.mirror.aliyuncs.com"]
    }    这个字典后保存->重启 
    sudo systemctl daemon-reload sudo systemctl restart docker

    docker查看容器中的进程

    docker top PID

    docker commit/pull使用

    docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
    -a :提交的作者
    -c :使用dockerfile指令来创建镜像
    -m:提交时的文字说明
    -p :在commit时,将容器暂停
    
    docker commit -a "rainbol" -m "提交了" 65asd2a mydocker:v1    #提交到本地
    
    docker push [OPTIONS] NAME[:TAG]        options:--disable-content-trust :忽略镜像的校验,默认开启
    docker push rainbol/mydocker:v1    #提交到dockerhub,需要登录账号

     docker数据卷  

      容器与主机数据共通,实现持久化和数据共享

    docker run -it -v /主机绝对路径:/容器绝对路径  镜像名        #建立数据挂载链接
    -v:开启卷 
    docker inspect sad213d     找到 volumes生成了一个字典并且hostconfig:binds中生成字典说明链接成功了
    此时主机和容器内这两个文件夹里面的数据资源共享共存,容器重启后数据同步
    
    docker run -it -v /主机绝对路径:/容器绝对路径:ro  镜像名     #ro(read only只读) 只允许主机单向的操作,容器只能进行读操作    在docker inspect sad213d命令中volumesRw会变成false

         没有指定宿主机docker默认会添加一个路径文件,可在inspect命令中查看

      dockerfile形式添加数据卷

      由于docker不支持docker run -it -v /主机绝对路径1:/容器绝对路径1 -v  /主机绝对路径2:/容器绝对路径2  存在迁移性

      引入dockerfile,建立更多的容器卷    

    docker数据卷容器

      说白了就是主容器与副容器的挂载链接,实现资源共享

    docker run -it --name test1 tomcat    #建立主容器
    docker run -it --name test2 --volumes-from test1 tomcat    # --volumes-from 被继承容器名,test2继承test1的所有,之后主容器和副容器的数据卷同步共享
    容器之间配置信息的传递,数据卷的生命周期一直持续到其没有容器使用为止,也就说在无限被继承中,无论哪个容器挂了,其资源共享,配置信息依旧存在

        1.构建可执行的shell脚本

    FROM tomcat
    VOLUME ["/data01","/data02"]
    CMD echo "finished,----success"
    CMD /bin/bash

        2.build生成镜像  

    docker build  -f /dockerfile文件绝对路径 -t rainbol/mytomcat /存放目录    #-f指定dockerfile路径 -t命名空间/镜像名称
    #如果build的dockerfile文件在当前目录可以不用写'-f dockerfile文件路径'

    dockerfile的使用

      dockerfile就是用来构建docker镜像的构建文件,说白了就是个执行参数和命令的脚本而已

      dockerfile文件规则:1.保留字指令必须大写,后面至少一个参数

                2.命令从上到下执行

                3.#表示注释

                4.每条指令都会创建一个新的镜像层,并对镜像进行提交(如FROM centos,加第一层进行,如果要再加其他的,就再加,这就是层层累加)

      FROM

    #第一条指令必须为 FROM 指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM 指令(每个镜像一次)

    FROM <images>
    FROM <image>:<tag>  
    FROM centos 
    FROM scratch
    #基础镜像->祖先源镜像

      MAINTAINER

        维护者信息(名字和邮箱)

      RUN

        容器运行时需要的额外命令

    RUN <command>  
    RUN chmod -R 777 tomcat-7
    
    RUN ["executable", "param1", "param2"] #使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"]
    RUN ["/bin/bash", "-c", "echo hello"]

      EXPOSE 

    EXPOSE <port> [<port>...]
    EXPOSE 8080 #告诉 Docker 服务端容器暴露的端口号

      WORKDIR

    WORKDIR /usr/local    #在创建后终端登录到容器后默认进入的工作目录

      ENV

    ENV <key> <value>    #设置环境变量
    ENV MY_TEST /usr/local
    WORKDIR $MY_TEST

      COPY

    格式为 COPY <src> <dest>。
    复制本地主机的 <src>(为 Dockerfile 所在目录的相对路径)到容器中的 <dest>。
    当使用本地目录为源目录时,推荐使用 COPY。

      ADD

    格式为 ADD <src> <dest>。
    该命令将复制指定的 <src> 到容器中的 <dest>。 其中 <src> 可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
    说白了add = copy + 自解压

      CMD

    支持三种格式
    
    CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;
    CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
    CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;
    指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。
    
    如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。

      ENTRYPOINT

    两种格式:
    ENTRYPOINT ["executable", "param1", "param2"]
    ENTRYPOINT command param1 param2(shell中执行)。
    配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。
    每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。
    说白了cmd是多个会被覆盖,而entrypoint多个会追加

      ONBUILD

    ONBUILD [INSTRUCTION]
    ONBUILD RUN echo '我被继承了--------ok'
    ONBUILD ADD a.txt /usr/local

        配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令

    案例1:

      重构centos镜像写一个dockerfile,初始路径为/usr/local,安装ifconfig,vim指令

    #/mydocker/dockerfile
    FROM centos
    MAINTAINER rainbol<xxx.com> ENV MYPATH
    /usr/local WORKDIR $MYPATH RUN yum -y vim RUN yum -y net-tools EXPOSE 80 CMD /bin/bash

      进入mydocker目录,运行

    docker build -t rainbol/mycentos .  #构建镜像
    

      

    docker run -it rainbol/mycentos /bin/bash  #运行

    docker history ID    # 查看docker历史构建信息,下图可以看到我们刚刚构建的信息

    案例2:

      重构centos镜像写一个dockerfile,初始路径为/usr/local,功能能访问ip.cn返回当前ip地址

    #/mydocker/dockerfile2
    FROM centos
    MAINTAINER rainbol<xxx.com>
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    RUN yum -y install curl
    ENTRYPOINT ["curl","-s","https://ip.cn"]  #注意这里参数不能为单引号,否则会报错
    EXPOSE 80
    CMD /bin/bash
    docker build -f /mydocker/dockerfile2 -t rainbol/mycentos:1.1 .  

      

    docker run rainbol/mycentos:1.1 -i
    #-i为curl请求头的参数,此时会在
    ENTRYPOINT追加参数

    案例3:

    #/mydocker/dockerfile_test01
    FROM centos
    MAINTAINER rainbol<xxx.com>
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    ONBUILD RUN echo '我居然被继承了'
    EXPOSE 80

      先构建上面dockerfile为test01  

    #/mydocker/dockerfile_test02
    FROM test01
    MAINTAINER rainbol<xxx.com>
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    EXPOSE 80

      当构建上面mydockerfile时返回,可以看到执行了ONBUILD中的命令 

    案例4  自建tomcat服务器

    1.在指定路径下存放tomcat.tar包和jdk,dockerfile文件,c.txt自建文档

    2. 编写dockerfile脚本

    #之前下载了centos,所以这里执行它
    FROM centos
    #命名作者 MAINTAINER rainbol
    <xxx@qq.com>
    #拷贝c.txt到容器中重命名一个文档(为了测试,意义不是很大) COPY c.txt /usr/local/cincontainer.txt
    #将jdk复制到容器指定位置,注意ADD指令可以自动解压缩 ADD openjdk
    -9.0.4_linux-x64_bin.tar.gz /usr/local/
    #将tomcat复制到容器指定位置 ADD apache-tomcat-9.0.12.tar.gz /usr/local/
    #下载vim RUN yum -y install vim

    #设置默认进入路径 ENV MYPATH
    /usr/local WORKDIR $MYPATH
    #设置环境变量 ENV JAVA_HOME
    /usr/local/jdk-9.0.4 ENV CATAINA_HOME /usr/local/apache-tomcat-9.0.12 ENV CATAINA_BASE /usr/local/apache-tomcat-9.0.12 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATAINA_HOME/bin #设置tomcat容器对外端口
    EXPOSE
    8080 #执行启动和查看打印日志命令
    CMD
    /usr/local/apache-tomcat-9.0.12/bin/startup.sh && tail -f /usr/local/apache-tomcat-9.0.12/logs/catalina.out

    3.build构建镜像

    docker build -f /mydocker/dockerfile_test01 -t test01  .

    4.启动镜像

    docker run -d -p 9876:8080 --name newmt9 -v /mydocker/rainbol/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.12/webapps/test -v /mydocker/rainbol/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.12/logs --privileged=true mt9
    
    #两个-v表示添加两个容器与主机挂载,一个是放应用或服务,一个是存放日志
    #--privileged=true 有可能会出现权限不足,那加这个

    5.测试  docker ps

    有页面返回说明启动成功

    安装mysql:

    docker pull mysql:5.6  #选择相对稳定的5.6版本
    docker run -p 12345:3306 --name mysql -v /
    docker run --name mysql56 -p 12345:3306 -v /mydocker/rainbol/mydockerfile/mysql5.6/conf:/etc/mysql/conf.d -v /mydocker/rainbol/mydockerfile/mysql5.6/logs:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6
    docker exec -it mysql56 /bin/bash

    安装jenkins

      https://www.jianshu.com/p/12c9a9654f83

    安装redis:

    docker pull redis:3.2
    docker run -p 2345:6379 -v /mydocker/rainbol/mydockerfile/redis3.2/data:/data -v /mydocker/rainbol/mydockerfile/redis3.2/conf/redis.conf:/usr/local/etc/redis/redis.conf -d redis:3.2 redis-server /usr/local/etc/redis/redis.conf --appendonly yes docker exec -it 0caf0428 redis-cli #连接容器内的redis客户端

    发布

      本地的镜像发布到阿里云上 

    1.镜像生成
    [root@rainbol redis3.2]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
    
    dc2e60009bcb        mt9                 "/bin/sh -c '/usr/lo…"   12 hours ago        Up 12 hours         0.0.0.0:9876->8080/tcp    newmt9
    
    
    [root@rainbol redis3.2]# docker commit -a rainbol -m 'newtomcat' dc2e60009bcb newtomcat1.2
    
    
    [root@rainbol redis3.2]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    newtomcat1.2        latest              15ce08832084        4 minutes ago       728MB

     https://cr.console.aliyun.com进入阿里云镜像服务,创建完仓库

      第二行的镜像版本号是为你想传到阿里云仓库的版本号

         第三行的镜像版本号和第二行你刚刚填的镜像版本号保持一致

       第三步推送时间比较长要等很久

    拉取阿里云的镜像

       私人:复制地址  docker pull 仓库地址:版本号  #注意可能出现多个版本,加版本号选择你想要的版本

      公开:  在镜像中心的镜像搜索进行下载镜像    docker pull 仓库地址:版本号  #注意可能出现多个版本,带版本号选择你想要的版本

    docker镜像打包  如果不存在云仓库,因为云上上传和下载很慢,或者是公司没网,怎么办呢,可以使用镜像打包的方法 

      docker save

    docker save [OPTIONS] IMAGE [IMAGE...]
    docker save -o 要保存的文件名  要保存的镜像id
    docker save -o /usr/local/nginx.tar jda090d1

      docker load

    docker load [OPTIONS]
    -i :指定导出的文件。
    -q :精简输出信息。
    
    docker load < /usr/local/nginx.tar
    docker load -i /usr/local/nginx.tar -q

    版权声明:本文原创发表于 博客园,作者为 RainBol 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。

  • 相关阅读:
    Cf序列化器-Serializer解析
    yield和return
    pymongo的使用
    Homebrew介绍和使用
    TypeError: expected string or bytes-like object
    JavaScript读取文本,并渲染在html
    反序相等
    打印邮票的组合
    打印对称平方数
    字符串按照原意输出
  • 原文地址:https://www.cnblogs.com/RainBol/p/11249375.html
Copyright © 2020-2023  润新知