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 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。

原文地址:https://www.cnblogs.com/RainBol/p/11249375.html