docker实战

参考资源:

docker练习的最佳环境:katacoda:https://www.katacoda.com/courses/docker/12

https://blog.csdn.net/qq_31293575/article/details/80663212

https://www.cnblogs.com/vikings-blog/p/3958091.html

docker技术入门与实战第二版

公司培训链接:

https://training.play-with-docker.com/

1.https://training.play-with-docker.com/bu

2.https://www.katacoda.com/courses/docker

3.https://www.katacoda.com/courses/docker-security

 

学习内容如下:

未解决问题:

1.from一个base镜像的 时候,会一直默认from到系统级?貌似是这样的,有一个base image的概念(没有parent image)。

2.docker镜像是不是指该镜像可以运行在任何docker环境中?不分windows还是linux?貌似是的,一次打包,到处运行

3.docker -d run xxx ls /tmp的时候是否会同时后台启动容器?还是仅仅是执行了一个ls命令?

一.基础部分:

docker是一个client-server架构,go开发的

docker一般指docker engine,不是docker machine

啥是docker client?还与docker engine通信?????日了狗了…… 

docker-machine:https://www.jianshu.com/p/cc3bb8797d3b,machine类似于k8s,是在远程主机上创建docker环境,即安装docker的一个牛逼的执行机,类似于ansible的执行机,可以在N多机器上同时安装docker并进行配置,也可以直接创建虚拟机并安装配置docker环境

 

docker engine,就是docker deamon

docker client,就是命令行工具

 

总结一下docker(docker daemon)和 docker client:docker daemon就是真正的docker server,可以处理镜像等等,具备处理的能力,而client就是个客户端,啥也干不了,具体执行全靠daemon。client干吗用?比如有一个server上装了docker daemon,不一定非要这个server上才能操作这个daemon,从别的机器上安装一个client,也能访问这个daemon,但是需要一顿猛如虎的操作(https://yq.aliyun.com/articles/581105),一般情况下都是当前server内部使用了。

1.docker search,查找镜像

2.docker run 运行镜像,参数,后台执行,-d。

3.docker ps 查找运行中的容器和更新时间

4.docker inspect friendlyname|container-id查看该镜像的详细信息

5.docker logs friendlyname|container-id 查看镜像标准输出日志

6.终极杀招,docker运行的标准命令,docker run  -d --name xxxx  hostport:containerport appname:version,这条命令可以在后台启动一个命名为xxxx的应用,主机上的容器的端口是hostsport,容器内应用的的端口是containerport,即通过hostsport即可找到该容器,通过containerport可以找到应用在容器中的端口。此时默认ip是0.0.0.0,如果要指定ip,可以改为:docker run  -d --name xxxx  ip:hostport:containerport appname:version,加的这个ip干嘛用的?外部链接的时候用的吧?

7.docker ps查找所有已创建且运行中的容器,查找所有包括已停止的容器,使用docker ps -a。

7.docker start/stop  container ID, 开始/结束容器,建立在容器已创建的基础上。用docker ps 可以查到。

8.删除容器,docker rm 容器1 容器2 容器3……

9.docker 操作时可以使用命名的那么,也可以采用容器的id。记住哪个都OK。--name这个参数很重要。

10.docker run -d --name redisDynamic -p 6379 redis:latest,这里面不指定主机的端口号,会随机分配一个端口号

11.docker内的文件持久化:docker是无状态的,容器消亡,目录下所有的东西也都没了,在启动的时候给容器指定一个工作空间volumes即可保存这些文件命令-v,docker run -d --name redisMapped -v /opt/docker/data/redis:/data redis,前一个地址是主机上的地址,后一个地址是容器内的地址

12.docker run -it ubuntu bash 创建并启动一个ubuntu容器,并进入bash命令行,有时候是/bin/bash,-it的作用是以交互模式生成容器

13.退出容器,ctl+P或者ctl+q

14.创建容器后可以使用docker inspect查看创建的容器的ip地址,ipaddress

15.docker build -t xxx:xx . 注意后面的一个点,表示在当前路径

16.dockerfile里的命令:http://www.cnblogs.com/dazhoushuoceshi/p/7066041.html

EXPOSE 端口 ,可以同时写多个或者一个端口段,如6000-7000

COPY:拷贝运行docker机器上的文件到容器内

RUN:运行指令,有两种写法,注意,在dockerfile中每执行一行就会建一层,所以RUN后面要写多行,换行符是\

CMD:容器启动时要运行的命令

WORKDIR: 容器内当前路径,当容器执行时,默认是在该目录下执行所有的命令

run和cmd的区别:run是构建容器时就运行的命令,cmd是容器启动时执行的命令

17.查看docker镜像的版本,docker search的时候是看不到版本的,在库中可以查看到,dockerhub中可以看到在tags里

18.docker cache机制:没时间搞,回头再说

19.dockerfile中的ONBUILD命令:在dockerfile中写这个东东,后面跟上dockerfile的命令,在该dockerfile内是不起作用也不执行的,只有这个景象被引用,引用的dockerfile才生效,比如景象a中有onbuild这个东东,只有当镜像b使用镜像a作为基础镜像时才执行onbuild的命令,且优先执行,子的子就没有了,只在第一级内执行这个。比如当a为一个模板,而基于a可以首先创建一些基础环境再引用a,比如创建应有的文件夹。

20.docker run xxx + 命令,比如docker run xxx ls /tmp 这个命令可以查看镜像下/tmp下的所有文件

21.dockerfile中copy和add的区别:add支持从url中获取文件,但是,推荐使用RUN wget,是不是很蛋疼?why??

22.忽略掉某些特殊文件,比如带有密码等信息的文件,在目录下创建一个.dockerignore文件,把文件路径或正则表达式填写在.dockerignore里面即可

23.如果必须要使用文件中的内容,就采用基本的run命令,然后删除文件,image只是记住最后的状态。

24.docker create:创建一个容器但不启动。

25.持久化,一种是持久化到本地,一种是持久化到某个容器,从容器中引用。有时候镜像是需要持久化的,比如数据库之类的,方法有俩,一个是在run的时候-v,一个是在create容器1的时候-v,即便不运行,当在另一个容器2启动并使用 --volumes-from 容器1参数时就可以直接调用容器1对应路径下的文件,容器1已经配置的文件会对容器2对应位置的文件进行替换。比如:

docker create -v /config --name dataContainer busybox;

docker run --volumes-from dataContainer ubuntu ls /config;此时查看时就可以看见ubuntu容器的/config下有dataContainer的/config下的文件

这样就做成了一个数据容器,也叫data Container

更牛逼的,当想把这些数据迁移到别的机器时:在当前机器执行docker export dataContainer > dataContainer.tar;在目标机器执行docker import dataContainer.tar即可把这个数据容器导入到目标机器上。

 

 

26.命令行拷贝文件到容器内:docker cp xxx 容器:路径,如docker cp config.conf dataContainer:/config/

26.docker pull: 从镜像库拉取或者更新指定镜像,默认是拉取latest的,如果要指定tags:docker pull xxx:version

27.网络连接部分:

a.同一个主机的容器之间,link的方式:第一步docker run --link redis-server:redis alpine,link一下,解释: -link 容器名称:容器别名(新起的别名) xxx容器。创建后再执行docker run --link redis-server:redis alpine ping redis,就可以看到pingOK了,或者用docker run --link redis-server:redis alpine cat /etc/hosts,可以看到在hosts内已经有redis对应的ip和域名映射了,而且是三个域名,真名,别名,还有一个hashid,前提是被链接容器是后台启动状态.

docker run -it --link redis-server:redis redis redis-cli -h redis,此命令启动了redis和其CLI

b.同一主机,容器之间,network的方式:原理是在/etc/resolve文件里加了一个域名解析地址,这个地址可以解析所有注册在这个地址上面的ip。。。docker network create xxxx(一个自定义的network的名字),对于之前创建的容器,可以使用docker network connect xxxx(前一步创建的network的名称) xxxxxx容器 , 生成network后,在启动容器时就可以使用docker run -d -p 3000:3000 --net=xxxnetwork名称  xxxxxx容器,也可以用别名的形式docker network create frontend-network2 docker network connect --alias db frontend-network2 redis,,,,docker run --net=frontend-network2 alpine ping -c1 db。

此时docker network有几个命令:docker network ls查看所有已创建的network。  docker network inspect xxxxnetwork, 这个命令可以查看该network下都有哪些容器。中断容器与这个network的连接:docker network disconnect xxxxnetwork xxx容器。

28.容器与主机,容器间的数据同步:

a.容器与主机间数据同步:docker数据同步,docker启动的时候会创建一个卷,这个卷用来共享docker与主机某个路径之间的数据。启动容器时使用-v命令,-v hostsdirectory:containerdirectory 当主机上没有该路径时会创建路径。实时同步的,还可以将这个文件夹的内容指向给另一个容器,docker run -v /docker/redis-data:/backup ubuntu ls /backup,这样就把redis-data文件夹下的内容同步到ubuntu容器的/backup下。

b.容器间数据同步:可以用于数据库升级时的数据保存。docker run --volumes-from r1 -it ubuntu ls /data,核心执行参数:--volumes-from xxx源容器。即从r1容器的文件同步到ubuntu容器的对应目录下,疑问:全部同步还是指定文件夹的同步????是双向的还是单向的?docker run -v /docker/redis-data:/data:ro -it ubuntu rm -rf /data,这里的冒号ro是禁止修改该数据

疑问:1.双向同步,-v的方式,yes?任何一方更改都会变化,yes?2.禁止。3,还有一种方式,在dockerfile内使用volume命令,但是这种方式只能定义容器内的路径,不能像-v那样指定主机上的其他路径

docker volume的参考:http://dockone.io/article/128

这个概念非常重要,可用于数据库同步以及部署,比如,在本地下载了代码,当容器启动时到本地路径下寻找代码并启动。

 

29.docker commit提交镜像到本地仓库 docker commit -m “xx” -a “xxx”  id 仓库名:版本号. 加-p可以让该容器暂停并创建新镜像

30.docker logs 查看容器运行日志,这些日志写在主机的一个目录下的一个json文件内,大量的容器会导致大量的日志文件,容器的日志处理可以在启动时使用--log-driver=syslog指向到syslog,还有一个办法是禁止打log,

31.docker确保是alive的:也叫uptime,restart on fail.启动时使用参数--restart=on-failure:n,n表示重启n次,n次之后不再重启。如docker run -d --name restart-3 --restart=on-failure:3 scrapbook/docker-restart-example,如果不限次数,只要挂了就重启,则使用--restart=always

 

32.docker用nginx进行负载均衡。还没看

33.很重要的概念:也是docker的灵魂,一个镜像可以生成多个容器。这些容器互不影响,

34.docker rmi 删除镜像  docker rm xxx删除容器(先停止kill或者stop,然后再rm)

35.docker system prune –f,强制删除容器所占的容器,卷,网络,镜像(未使用或悬空 的镜像)等https://www.jianshu.com/p/470e29801be2

36.docker system df,查看docker资源占用情况,比如磁盘。

 

35.修改镜像步骤:运行一个容器,在容器内修改(比如进入后执行一个yum install,或者命令行的方式),容器必须是运行中?,退出容器(exit),然后用docker commit 命令把容器提取成镜像并加备注(docker commit -m "信息"-a "作者" 容器id 镜像名:版本),其中要指定容器的id和新镜像的名称和版本,这样本地就有一个镜像了,然后用push推到远程仓库

36.docker file中的ENTRYPOINT和CMD:ENTRYPOINT作用,都是在启动容器时执行,EN是不可被覆盖的,容器启动时第一个执行,如果有多个,以最后一个为准。可以通过 --entrypoint替换。CMD随时可被run时的command替换,当也有entry时也作为entry的参数,具体见https://blog.csdn.net/taiyangdao/article/details/73214449

37.docker RUN和CMD区别:run是在创建镜像时执行,CMD是启动容器时执行

38.docker exec:在运行的容器中执行命令。与run的区别:https://blog.csdn.net/dt763C/article/details/82719332。run会启动一个新容器,而exec是在一个已经启动的容器中执行命令,经典命令docker exec -it 容器名 /bin/bash 进入容器中。就可以随意敲命令行。或者把/bin/bash直接换成命令

 

※dockerfile:

1.RUN,每执行一次就增加一个镜像,想同时执行多个,可以使用&&。写法是每行行首写一个&&,行尾写一个\

2.dockerfile中每一个命令都会建一层

3.ENV:

 

 

 

首先吐槽一下csdn:二次提交竟然会覆盖。这个业务逻辑太扯了,十分的扯,差评!

 

一.用docker将app打包一个镜像:

问题:

1.内部特殊端口号怎么处理的?

2.是在外面gradle还是内部gradle比较好?

3.java项目和python项目的案例?

 

实践步骤:

1.jenkins内创建job

2.jenkinsfile分三步:artifactory创建gradle并进行构建,使用dockerfile进行创建镜像,tag打上标签,push到远程仓库

3.slave内使用artifactory 的newgradlebuild创建gradle,同时制定一个artifactory的server用于存储。具体google

 

 

dockerfile内的技巧:

1.基于某个镜像

2.用COPY 把前一步gradle的zip拷贝到镜像内,解压,把jar和lib下的所有文件cp(在RUN内执行)到/webapps/root/web-int/lib下,删除临时zip包,用RUN修改一些配置文件和环境变量。最后执行CMD ["catalina.sh", "run"],这个CMD是在容器启动时执行,有别于run的创建镜像时执行

 

技巧:

1.有两种动作,用于创建镜像和打包的,静态的,使用RUN,这些在创建镜像过程中完成。

2.用于在容器启动时执行的,用CMD和ENTRYPOIT,比如容器启动时启动tomcat。

3.docker system prune -al 清除掉所有已停的镜像以节省空间,docker system在docker 的1.13版本之后才有的命令,后面加dh可以查看docker系统占用了多大空间

 

docker tag的作用:为啥要docker tag然后再docker push?针对已有的镜像,创建一个带有新标签的新镜像,针对远程镜像库,远程创建一个带有新标签的新镜像(前提是有远程库的ip:端口),

 

实战:

dockerfile案例1:

from xxx

RUN  后面如果有多个命令,换行写的时候,结尾用  ' &&\ ' 

COPY 

WORKDIR:指定容器启动时的工作目录,针对后面的命令有效

ENTRYPOINT:容器启动后执行的命令,且一个dockerfile内只能有一个,类似于CMD,但是会被覆盖

USER:指定执行的用户名字

 

 

进入到运行中的容器; docker exec -it 容器名 /bin/bash

 

》》》》》》》》》

从零开始,以jenkins为例:

安装 yum install,选择docker而不是docker client

执行下面代码

 

docker run \
-u root \
--rm \
-d \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkinsci/blueocean

 

这个时候会报一个错误:/usr/bin/docker-current: Error response from daemon: driver failed programming external connectivity on endpoint gallant_mclean (5ad14ff0ee6d58001cf64188306233b8bfa5e35bf052a60e768aa38509fab080): exec: "docker-proxy": executable file not found in $PATH

 

解决方案:

cd /usr/libexec/docker/        ln -s docker-proxy-current docker-proxy

 

再执行一次那堆run,报新的错误,因为之前执行过一次导致端口50000被占用,然后咋办?

报错内容:

/usr/bin/docker-current: Error response from daemon: driver failed programming external connectivity on endpoint friendly_poitras (fd438b6f96fbe999b665749333a5a30a70cb7af2540adeaf4a6105983bde7c72): Bind for 0.0.0.0:50000 failed: port is already allocated

解决方案 及原因:

 

docker清理所有的东西:docker container prune   docker image prune   docker volume prune   docker rm -lv CONTAINER

上面所有的清楚步骤可以凝结为:docker system prune –f

 

从零开始使用:

docker build -t name:tag .   后面有个点

docker tag 镜像id 旧名字 新名字

docker run -it 镜像名 sh  有的时候是/bin/bash  这样就会直接进入到一个容器。也可以 docker run -d 镜像名 后台运行并返回一个id

docker 构建镜像时,在拷贝jar包后执行一个 RUN sh -c "touch app.jar",原因?当执行touch时,该命令会修改这个文件的时间戳。这样当执行拷贝的时候就可以覆盖,而不是不替换。因为文件在替换的时候会检查checksum。如果新建一个时间戳就可以确保每次这个文件检查的时候都不一样。然后就会成功替换。

docker 后面一点 “.” 的作用:指定上下文  https://blog.csdn.net/Michaelwubo/article/details/82385332

docker -e 额外的变量

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值