系统学习Docker 践行DevOps理念 笔记(二)|Docker的镜像和容器
Docker的镜像和容器,是课程第三章的内容
1.Docker架构和底层技术简介
2.Docker Image概述
|
|
Image的获取方法:
- Build from dockerfile
- pull from registry (https://hub.docker.com/explore/,或者是其他私有仓库)
3.DIY一个Base Image
3.1优化输入docker命令的时候不用加sudo
sudo groupadd docker
,创建docker用户组,不过这个组一般安装好docker之后就会有了sudo gpasswd -a vagrant docker
,把vagrant这个用户加入到docker用户组- 有的时候会需要重新打开terminal才可以
3.2通过Dockerfile简单构建镜像
|
|
docker build -t liguoqinjim/hello-world .
,构建镜像的命令,".“表示在当前目录里面找Dockerfile,-t指定了镜像的名称
4.初识Container
4.1容器相关命令:
docker container ls
,列出现在正在运行的容器docker container ls -a
,列出所有的容器,包括没有在运行的docker ps -a
,列出所有的容器,包括没有在运行的docker run -it centos
,交互式运行容器的方法,这样的话运行之后contianer不会退出,但是这个对话关闭这个,contianer还是就会退出了docker container rm container_id
,可以删除一个容器(注意,这里的id可以是完整的容器id,也可以是缩写,只要是可以和别的id区分开的就可以了)docker rm container_id
,默认就是去删除container的,所以是和docker container rm id是一样的docker images
,和docker image ls是一样的,显示本机的所有镜像docker image rm image_id
,删除image,可以是image_id或者image_namedocker rmi id
,是和docker image rm id一样的,是简写docker container ls -aq
,只会显示出容器的id,在批量删除容器的时候有用docker rm $(docker container ls -aq)
,删除所有的容器docker rm $(docker ps -aq)
,也是删除所有的容器docker rm $(docker container ls -f "status=exited" -q)
,删除所有不在运行的容器
4.2docker镜像拉取加速:
5.构建自己的Docker镜像
有两种方法可以构建镜像,一种是通过容器创建,我们创建一个容器,比如在里面安装软件,安装完成之后,我们把这个容器commit成镜像。 还有一种是通过Dockerfile来打包镜像。比较推荐Dockerfile的方式,因为使用Dockerfile别人可以清楚看到这个镜像是怎么打包的。 但是要是我们使用commit的方式,别人无法了解我们是怎么生成镜像的,有没有发一些恶意代码等等。
5.1docker commit的方式创建镜像
docker commit docker_name liguoqinjim/centos_vim
这个命令就是把docker_name这个容器,生成一个镜像,镜像的名称是liguoqinjim/centos_vim
5.2使用Dockerfile创建镜像
docker build -t liguoqinjim/centos_vim_new .
“.“表示使用当前目录的Dockerfile来创建镜像,liguoqinjim/centos_vim_new就是镜像的名字
NOTICE
在docker中镜像是只读的,也就是不能写的。那么docker是怎么实现在镜像里面安装好vim的呢?
这是因为docker会自动启动一个container,然后在container里面安装vim,然后再通过这个container来制作成镜像。
6.Dockerfile语法梳理及最佳实践
Dockerfile命令:
6.1FROM
尽量使用官方镜像作为base image
|
|
6.2LABEL
设置Metadata
|
|
6.3RUN
run命令为了美观,最好使用反斜杠换行。
每运行一次run,image都会生成新的一层,所以尽量合并多条命令成为一行
|
|
6.4WORKDIR
能用WORKDIR的就用WORKDIR,不要用RUN去运行cd命令。
WORKDIR后面跟的路径也可以尽量使用绝对路径
|
|
6.5ADD and COPY
大部分情况下COPY是要优于ADD的,但是ADD有一个解压缩的功能。
要是想添加远程文件的话,可以用RUN命令来运行curl或者wget
|
|
6.6ENV
使用ENV可以增加可维护性
|
|
NOTICE
可以参考官方给出的一些例子,和一些官方镜像的Dockerfile
链接:
7.RUN vs CMD vs ENTRYPOINT
RUN
:执行命令并创建新的Image LayerCMD
:设置容器启动后默认执行的命令和参数ENTRYPOINT
:设置容器启动时运行的命令
这三个命令里面,CMD和ENTRYPOINT是一组的,RUN和他们两个是不一样的
7.1Shell和Exec格式的区别
Shell格式
|
|
|
|
###Exec格式
|
|
|
|
NOTICE
SHELL格式的时候,echo "hello $name"
是会把$name替换掉的,
但是在Exec的格式中,直接使用ENTRYPOINT ["/bin/echo","hello $name"]
是不会把$name替换掉的,因为这样不是在shell中运行,只是调用了echo命令
想要替换掉$name,需要用ENTRYPOTIN ["/bin/bash","-c","echo hello $name"]
7.2CMD和ENTRYPOINT的区别
CMD
ENTRYPOINT
NOTICE
- CMD是可能会被忽略的,但是ENTRYPOINT不会
- 如果定义多个CMD,只有最后一个会被执行
8.镜像的发布
镜像的发布一共有三种方式:
- docker push到hub docker
- docker hub和github相连接,我们在github里面写好dockerfile,docker hub会自动打成镜像
- 自建docker registry
8.1docker push
|
|
8.2docker hub和github相连接
8.3自建docker registry
- 启动docker registry,
docker run -d -p 5000:5000 --restart always --name registry registry:2
- 修改/etc/docker/daemon.json
在deamon.json里面添加,“insecure-registries:[“10.75.44.222:5000”]",10.75.44.222就是本机的ip - 重启docker
docker push localhost:5000/hello-world
,推送镜像到docker registry,注意image的开头一定要是docker registry的地址- 可以通过api查看是否push成功,
curl localhost:5000/v2/_catalog
,这个是docker registry提供的api
9.Dockerfile实战
怎么把一个写好的服务放进docker里面:
- 先FROM编程语言的官方库
- RUN命令安装需要的依赖,如(pip install等)
- 把程序放进通过ADD或者COPY放到镜像里面
- EXPOSE 端口,把服务的端口暴露
- CMD里面运行程序即可
docker run -d image_name
,这样我们就运行了这个镜像,且是在后台运行
NOTICE
在创建镜像的时候要是出错的话,因为docker在创建镜像的时候,每一步都会创建一个中间镜像。要调试的时候,我们可以run这些中间镜像去调试,比如docker run -it 中间镜像id /bin/bash,就可以进入启动一个这个镜像的容器,然后进入内部查看有什么错误
10.容器的操作
关于容器的几个命令:
docker run -d --name=demo liguoqinjim/flask-hello-world
,运行一个容器,–name可以指定容器的名称,不然docker会指定一个随机的名称docker exec -it container_id /bin/bash
,exec可以让容器执行一个命令,在这个命令里面我们用交互式的方式执行/bin/bash,执行完之后我们就会进入容器内部。当然也是可以执行其他的命令的docker exec -it container_id ip a
,运行ip a命令docker stop container_id
,停止一个容器docker start container_id
,启动一个容器docker inspect container_id
,查看一个容器的详细参数docker logs container_id
,会打印出容器里面的输出
11.Dockerfile实战(2)
docker的容器大致可以分类两类,一种是app或者服务,就是一直运行在后台的程序。还有一种就是工具类的,运行一次出个结果。
这里引入一个linux下的工具软件,stress,是一个linux系统下测试系统性能的工具。
安装:apt-get update && apt-get install -y stress
使用:stress --vm 1 --verbose
使用ENTRYPOINT和CMD配合来获得运行容器时候输入的参数,ENTRYPOINT是要运行的命令,CMD获取运行容器时候输入的命令
如:docker run -it liguoqinjim/ubuntu-stress --vm 1
,这样--vm 1
就传给了/usr/bin/stress
并运行
|
|
12.容器的资源限制
可以在容器运行的时候加上参数对容器的资源进行限制。
12.1限制内存
|
|
–memory设置了300M内存,但是要是没有设置–memory-swap的话,他的默认值就和–memory一样。那么在–memory设为200的时候,机器的内存就可以认为是200的memory加上200的memory-swap,也就是400M的内存,在上面这个命令中就是600M内存
12.2限制cpu
|
|
–cpu-shares是docker的参数,–cpu是给stress的参数。–cpu-shares就是当有多个设置了–cpu-shares的时候,他们分配的到的cpu就是他们的权重。比如上面的情况就是test1可以使用大约66%的cpu,而test2可以使用33%