简介
- 将物理设备和app用docker engine隔离
后台进程dockerd+rest api server+cli接口(docker)(cs架构)
3.docker version123456789101112131415161718client:Version: 18.09.6API version: 1.39Go version: go1.10.8Git commit: 481bc77Built: Sat May 4 02:35:27 2019OS/Arch: linux/amd64Experimental: falseServer: Docker Engine - CommunityEngine:Version: 18.09.6API version: 1.39 (minimum version 1.12)Go version: go1.10.8Git commit: 481bc77Built: Sat May 4 01:59:36 2019OS/Arch: linux/amd64Experimental: falsecontainers + images + registry
- 底层技术支持
- namespace;做隔离pid,net,ipc,mnt,uts
- control groups:做资源控制,内存 cpu等
- union file systems:container 和image的分层
- 实验环境介绍
docker image镜像
image概念
- 文件和meta data的集合(root filesystem)
- 分层,每层都可以添加改变删除文件,成为一个新的image
- 不同的image可以共享相同的layer
- image本身是read only
- linux内核和发行版和基于一些应用软件都可以看做是docker的分层
- 12345678910111213root@swoole_dev:/home/tb# docker image lsREPOSITORY TAG IMAGE ID CREATED SIZEhello-world latest fce289e99eb9 5 months ago 1.84kBroot@swoole_dev:/home/tb# docker run centosUnable to find image 'centos:latest' locallylatest: Pulling from library/centos8ba884070f61: Pull completeDigest: sha256:ca58fe458b8d94bc6e3072f1cfbd334855858e05e1fd633aa07cf7f82b048e66Status: Downloaded newer image for centos:latestroot@swoole_dev:/home/tb# docker image lsREPOSITORY TAG IMAGE ID CREATED SIZEcentos latest 9f38484d220f 3 months ago 202MBhello-world latest fce289e99eb9 5 months ago 1.84kB
为啥centos这么小,因为他是基本地于linux kernel的基础之上
image的获取方式
- dockerfile,build
- from ubuntu:14.04 基于的base kernel
- label 说明
- run 执行的命令
- expose 暴露的端口
- entrypoint:程序起点,入口
- docker build -t tongbo/redis: latest .,.代表当前目录
- 执行build的每一行的id就是一层封装,层之间可以互用
pull from registry(类似github,默认的为dockerhub)
- docker pull ubuntu:14.04
- docker push (to server) 12345678910111213141516171819root@swoole_dev:/home/tb# docker pull redis:3.23.2: Pulling from library/redisf17d81b4b692: Pull completeb32474098757: Pull complete8980cabe8bc2: Pull complete58af19693e78: Pull completea977782cf22d: Pull complete9c1e268980b7: Pull completeDigest: sha256:43d2f5e7338ef56b3bda52f1ba7b9b58866c07141e834f64267afb51c89e5086Status: Downloaded newer image for redis:3.2root@swoole_dev:/home/tb# docker image lsREPOSITORY TAG IMAGE ID CREATED SIZEcentos latest 9f38484d220f 3 months ago 202MBhello-world latest fce289e99eb9 5 months ago 1.84kBredis 3.2 87856cc39862 8 months ago 76MBroot@swoole_dev:/home/tb# docker search redisNAME DESCRIPTION STARS OFFICIAL AUTOMATEDredis Redis is an open source key-value store that… 7029 [OK]bitnami/redis Bitnami Redis Docker Image 114
dockerhub
- offical
- 第三方的,pull的时候需要增加用户名/镜像名字
- dockerfile,build
制作base image
- 比如制作一个u2dev的base
- 小技巧:如何去掉sudo,sudo groupadd docker sudo gpasswd -a vargant docker service docker restart
- 以hello-world的image为例
- tag
- digest(摘要,消化理解)
- status
- more ambitious(有野心的,有兴趣的)
-12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455# 编辑dockerfile文件FROM scratch #base的image,所以从开始不需要ADD hello / #把helloadd到image的根目录里CMD ["/hello"] #执行脚本命令#build,根据dockerfile,一共三步@swoole_dev:/home/tb/my_docker_helloworld# docker build -t tongbo/hello_world .Sending build context to Docker daemon 12.29kBStep 1/3 : FROM scratch--->Step 2/3 : ADD hello /---> b89e60e00ca1Step 3/3 : CMD ["/hello"]---> Running in 13d1d20bd719Removing intermediate container 13d1d20bd719---> 462eb2d91ad7Successfully built 462eb2d91ad7Successfully tagged tongbo/hello_world:latestroot@swoole_dev:/home/tb/my_docker_helloworld##build成功,查看结果root@swoole_dev:/home/tb/my_docker_helloworld# docker image lsREPOSITORY TAG IMAGE ID CREATED SIZEtongbo/hello_world latest 462eb2d91ad7 55 seconds ago 8.6kBcentos latest 9f38484d220f 3 months ago 202MBhello-world latest fce289e99eb9 5 months ago 1.84kBredis 3.2 87856cc39862 8 months ago 76MBroot@swoole_dev:/home/tb/my_docker_helloworld## 查看镜像分层(因from scratch,所以这里是两层)root@swoole_dev:/home/tb/my_docker_helloworld# docker history 462eb2d91ad7IMAGE CREATED CREATED BY SIZE COMMENT462eb2d91ad7 3 minutes ago /bin/sh -c #(nop) CMD ["/hello"] 0Bb89e60e00ca1 3 minutes ago /bin/sh -c #(nop) ADD file:ab92082ce376d310a… 8.6kBroot@swoole_dev:/home/tb/my_docker_helloworld## build 自己的镜像时候必须是gcc -static,否则报文件不存在,==这是为啥内==# -static 是让 gcc 进行静态编译,也就是把所有都需要的函数库都集成进编译出来的程序上,这个程序就可以不依赖外部的函数库运行了。root@swoole_dev:/home/tb/my_docker_helloworld# docker run tongbo/hello_worldstandard_init_linux.go:207: exec user process caused "no such file or directoryroot@swoole_dev:/home/tb/my_docker_helloworld# gcc -static hello.c -o helloroot@swoole_dev:/home/tb/my_docker_helloworld# docker build -t tongbo/hello_world .Sending build context to Docker daemon 916.5kBStep 1/3 : FROM scratch--->Step 2/3 : ADD hello /---> Using cache---> 11b009df24b2Step 3/3 : CMD ["/hello"]---> Using cache---> 6c539eb137ddSuccessfully built 6c539eb137ddSuccessfully tagged tongbo/hello_world:latestroot@swoole_dev:/home/tb/my_docker_helloworld# docker run tongbo/hello_worldhello,world,docker in c
什么是container
- container是通过image创建(copy)的
- container是在image上的基础上增加类一层,叫做container layer,后者是可读写 的,注意image是只读的
- 理解: 类为image,实例为container
- image负责app的存储和分发,container负责运行
基于image 创建container
- docker run image
- docker container ls:查看当前正在运行的容器
- docker container ls -a:查看当前运行和已经运行完成退出的
- 123root@swoole_dev:/home/tb/my_docker_helloworld# docker container ls -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES51869bc1fcd5 tongbo/hello_world "/hello" 7 minutes ago Exited (0) 7 minutes ago happy_bardeen
docker run centos:注意一般run会走latest的版本,如果指定类版本,必须加上,否则会先pull一份过来,下面的执行centos ,==也只是走类bin/bash,why?==
1234567root@swoole_dev:/home/tb/my_docker_helloworld# docker run centosroot@swoole_dev:/home/tb/my_docker_helloworld# docker container lsCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESroot@swoole_dev:/home/tb/my_docker_helloworld# docker container ls -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES35f4015c37be centos "/bin/bash" 20 seconds ago Exited (0) 18 seconds ago gallant_boyd51869bc1fcd5 tongbo/hello_world "/hello" 11 minutes ago Exited (0) 11 minutes ago happy_bardeen交互式运行
- docker run -it centos123456789101112# 终端1,ununtu环境root@swoole_dev:/etc/docker# docker container lsCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES29fae6a620a9 centos "/bin/bash" 47 seconds ago Up 46 seconds affectionate_meitnerroot@swoole_dev:/etc/docker# docker container lsCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES29fae6a620a9 centos "/bin/bash" 51 seconds ago Up 49 seconds affectionate_meitnerroot@swoole_dev:/etc/docker## run -it centos 效果,-i为interactive,-t为tty,通过执行 docker run --help查看,完成操作后再容器内退出,退出后容器不会运行[root@29fae6a620a9 /]# cat /etc/redhat-releaseCentOS Linux release 7.6.1810 (Core)[root@29fae6a620a9 /]#
- docker run -it centos
docker的management commands和commands
Management Commands:
123456789101112131415builder Manage buildsconfig Manage Docker configscontainer Manage containersengine Manage the docker engineimage Manage imagesnetwork Manage networksnode Manage Swarm nodesplugin Manage pluginssecret Manage Docker secretsservice Manage servicesstack Manage Docker stacksswarm Manage Swarmsystem Manage Dockertrust Manage trust on Docker imagesvolume Manage volumes一些简写 命令
- docker rmi imageid
- docker rm containerid
- docker ps -a 当前的container
- docker container ls -aq 列出所有的container id
- docker rm $(docker container ls -aq) rm所有的container
- 结合xargs grep awk
- docker container ls -f “status=exited” -q 删除所有exited的container
构建自己的docker镜像
- docker container commit
- Usage: docker container commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] Create a new image from a container’s changes
- 简写为 docker commit
- docker build
- build an image from a dockerfile
操作步骤
- docker run -it centos
- yum install vim
- exit
- docker container ls -a |grep centos
- 4中的centos 安装了vim
docker container ls -a |grep centos 0f5ccf1365eb centos "/bin/bash" 3 minutes ago Exited (0) About a minute ago pedantic_gagarin
- 12345678root@swoole_dev:/home/tb# docker commit pedantic_gagarin yaxiaomu/centos_add_vim:default_yaxiaomu_tagsha256:3204e122d66ce500790269c1fed291842b6f18c34286647212d9293c9f56cb45root@swoole_dev:/home/tb# docker image lsREPOSITORY TAG IMAGE ID CREATED SIZEyaxiaomu/centos_add_vim default_yaxiaomu_tag 3204e122d66c 10 seconds ago 361MBtongbo/hello_world latest 6c539eb137dd 17 hours ago 913kBcentos latest 9f38484d220f 3 months ago 202MBredis 3.2 87856cc39862 8 months ago 76MB
注意centos和centos_add_vim这两个image会共享很多的layer:
9f38484d220f
1234567891011121314151617root@swoole_dev:/home/tb# docker image lsREPOSITORY TAG IMAGE ID CREATED SIZEyaxiaomu/centos_add_vim default_yaxiaomu_tag 3204e122d66c 3 minutes ago 361MBtongbo/hello_world latest 6c539eb137dd 17 hours ago 913kBcentos latest 9f38484d220f 3 months ago 202MBredis 3.2 87856cc39862 8 months ago 76MBroot@swoole_dev:/home/tb# docker history 9f38484d220fIMAGE CREATED CREATED BY SIZE COMMENT9f38484d220f 3 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B<missing> 3 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B<missing> 3 months ago /bin/sh -c #(nop) ADD file:074f2c974463ab38c… 202MBroot@swoole_dev:/home/tb# docker history 3204e122d66cIMAGE CREATED CREATED BY SIZE COMMENT3204e122d66c 3 minutes ago /bin/bash 160MB9f38484d220f 3 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B<missing> 3 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B<missing> 3 months ago /bin/sh -c #(nop) ADD file:074f2c974463ab38c… 202MB
不提倡以上方式创建,提倡用dockerfile,再build
123456789101112131415#如何在docker image里yum呢,image不是只读的吗# 答:会产生临时的container,然后再写,然后再commitroot@swoole_dev:/home/tb/docker-centos-vim# docker build -t tongbo/centos_add_vim .Sending build context to Docker daemon 2.048kBStep 1/2 : FROM centos---> 9f38484d220fStep 2/2 : RUN yum install -y vim---> Running in 67aeb36048ffLoaded plugins: fastestmirror, ovl...Complete!Removing intermediate container 67aeb36048ff---> 907325d6fc6bSuccessfully built 907325d6fc6bSuccessfully tagged tongbo/centos_add_vim:latest
dockerfile语法梳理和最佳实践
- FROM [scratch centos ubuntu:14:04] #制作|使用base image
- 尽量使用官方image
- LABEL metadata autohr verison description
- RUN yum install |apt-get update(注意执行命令都会有新的一层layer,尽量合并成一个语句(&&连接,反斜线\换行),减少层数)
- workdir /root |demo |pwd(如果没有目录会再当前目录自动创建,注意使用绝对目录)
- ADD把本地文件条件,添加到image的根目录里去,也可以解压缩
- ADD test.tar.gz/ # 添加到根目录并解压
- COPY ,大部分情况使用copy,如果添加远程文件用curl 或者wget
ENV mysql_version 5.6 # 设置常量, 保证可维护性
123ENV MYSQL_VERSION 5.6RUN apt-get instlal -y mysql-server= "${MYSSQL_VERSION}" \&& rm -rf /var/lib/apt/lists/*volume 和rescource
- CMD and entrypoint
- docker-library on github, reference
run vs cmd vs encrypoint
- run:执行命令并创建新的image layer
cmd:设置容器启动后默认执行的命令和参数
- 如果docker run指定了其他命令,cmd命令会被忽略
- docker run -it [image] /bin/bash
- 如果定义类多个cmd,仅有最后一个被执行
- 如果docker run指定了其他命令,cmd命令会被忽略
entrypoint:设置容器启动时运行的命令
- 不会被忽略,一定会执行,即使指定了其他命令(区别于cmd)
- 让容器以应用程序或者服务的形式运行
- 实践:写一个shell脚本作为entrypoint
-
- 两种格式
- shell格式 run echo “hello”
- exec格式 [“/bin/echo”,’hello’]
- 如果是exec格式,需要显示指定如下123FROM centosEVN name DockerENTRYPOIN ["/bin/bash","-c","echo hello $name"]
image的分发
dockerhub
- docker login
- docker image push 12345678910111213141516171819202122root@swoole_dev:/home/tb/my_docker_helloworld# docker push yaxiaomu/hello_world:latestThe push refers to repository [docker.io/yaxiaomu/hello_world]096f9105d9f4: Pushedlatest: digest: sha256:dc9c69395640d5fd7cb9e4f8bd2bdbf788b206a59e942a2a40577d9b1c089934 size: 527root@swoole_dev:/home/tb/my_docker_helloworld## 注意image必须是dockerid的用户名,否则会说:denied: requested access to the resource is denied# 本地删除后再次从docker hub上pullroot@swoole_dev:/home/tb/my_docker_helloworld# docker run yaxiaomu/hello_worldhello,world,docker in croot@swoole_dev:/home/tb/my_docker_helloworld# docker rm yaxiaomu/hello_worldError: No such container: yaxiaomu/hello_worldroot@swoole_dev:/home/tb/my_docker_helloworld# docker rmi yaxiaomu/hello_worldUntagged: yaxiaomu/hello_world:latestUntagged: yaxiaomu/hello_world@sha256:dc9c69395640d5fd7cb9e4f8bd2bdbf788b206a59e942a2a40577d9b1c089934root@swoole_dev:/home/tb/my_docker_helloworld# docker run yaxiaomu/hello_worldUnable to find image 'yaxiaomu/hello_world:latest' locallylatest: Pulling from yaxiaomu/hello_worldDigest: sha256:dc9c69395640d5fd7cb9e4f8bd2bdbf788b206a59e942a2a40577d9b1c089934Status: Downloaded newer image for yaxiaomu/hello_world:latesthello,world,docker in croot@swoole_dev:/home/tb/my_docker_helloworld#
因为安全因素考虑,分享image不如分享Dockerfile
- 可以通过和github关联,自动拉取指定项目下的dockerfile,自动build
- 私有本地仓库搭建,但没有图形化界面:docker run -d -p 5000:5000 –restart always –name registry registry:2
- 可以向指定私有库提交docker built -t serverip:port/name:tag
- 安全性修改,创建文件/etc/docker/daemon.json deamon.json,配置加入 insecure-registries: ip :端口
- 再修改 root@swoole_dev:/etc/init.d# vim /lib/systemd/system/docker.service,增加一行:EnvironmentFile=/etc/docker/daemon.json
- 重启docker服务 service docker restart
- 通过docker registry api 查看 ,http查看
- 记录在了segmentfault
dockerfile实战
- flask demo,把python程序打包成image,运行container
- 准备一个带pyhton的base image
- 需要安装flask
- 需要运行起来app
操作步骤
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566root@swoole_dev:/home/tb/flask_demo# more app.py## app.pyfrom flask import Flaskapp = Flask(__name__)@app.route('/')def hello():return "hello,tb de docker"if __name__ == '__main__':app.run()# 安装软件apt-get install python-minimalapt install python-pippip install flask# 运行结果root@swoole_dev:/home/tb/flask_demo# python app.py* Serving Flask app "app" (lazy loading)* Environment: productionWARNING: This is a development server. Do not use it in a production deployment.Use a production WSGI server instead.* Debug mode: off* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)127.0.0.1 - - [22/Jun/2019 21:00:05] "GET / HTTP/1.1" 200 -#dockerfile ,注意cppy的 app.py为写成类绝对路径报错类,那就转移到当前目录下吧。FROM python:2.7LABEL maintainer="tongbo<demo.com@126.com>"RUN pip install flaskCOPY app.py /app/WORKDIR /appEXPOSE 5000CMD ["pyhton","app.py"]# buildroot@swoole_dev:/home/tb/flask_hello_world# docker build -t yaxiaomu/flask_demo:latest .Sending build context to Docker daemon 3.072kBStep 1/7 : FROM python:2.7---> 37093962fbf5Step 2/7 : LABEL maintainer="tongbo<demo.com@126.com>"---> Using cache---> c4ac0caa5aabStep 3/7 : RUN pip install flask---> Using cache---> 60c7e35f23a3Step 4/7 : COPY app.py /app/---> a7a69c1da0b6Step 5/7 : WORKDIR /app---> Running in 2122fe24efd6Removing intermediate container 2122fe24efd6---> f6b586c33cbcStep 6/7 : EXPOSE 5000---> Running in e368df4c5205Removing intermediate container e368df4c5205---> 6a7e1858c5e7Step 7/7 : CMD ["pyhton","app.py"]---> Running in e8c96756cc9eRemoving intermediate container e8c96756cc9e---> c37bb4c557daSuccessfully built c37bb4c557daSuccessfully tagged yaxiaomu/flask_demo:latest## 运行container,报错root@swoole_dev:/home/tb/flask_hello_world# docker run yaxiaomu/flask_demodocker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"pyhton\": executable file not found in $PATH": unknown.ERRO[0000] error waiting for container: context canceleddebug
- 针对创建临时中间状态的image,根据image id进入/bin/bash
- docker run it imageid /bin/bash
- cd .. && begin your debug
123456789101112131415161718192021root@swoole_dev:/home/tb/flask_hello_world# docker run -it c37bb4c557da /bin/bashroot@a972581ff13e:/app#root@a972581ff13e:/app# python app.py* Serving Flask app "app" (lazy loading)* Environment: productionWARNING: This is a development server. Do not use it in a production deployment.Use a production WSGI server instead.* Debug mode: off* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)## 看结果明明可以运行,再看报错,原来是python写成pyhton了。改一下dockerfile,成功了root@swoole_dev:/home/tb/flask_hello_world# docker run yaxiaomu/flask_demo* Serving Flask app "app" (lazy loading)* Environment: productionWARNING: This is a development server. Do not use it in a production deployment.Use a production WSGI server instead.* Debug mode: off* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)## 后台运行 docker run -d,--name 增加名字,删除启动时可用root@swoole_dev:/home/tb/flask_hello_world# docker run -d --name tb_demo yaxiaomu/flask_demoe7841af659ab469f598151b0f43c1333a77a52c6610d6894a5dfbec887d6848e
容器的操作
docker container stop 664f2033265b | docker stop 664 664f2033265b [1]+ Exit 137 docker run yaxiaomu/flask_demo
root@swoole_dev:/home/tb/flask_hello_world# docker exec -it e7841af659ab /bin/bash root@e7841af659ab:/app#
- docker exec -it e7841af659ab ip a
- docker rm $(docker ps -aq)
- docker start|stop demo
- docker inspect containerId # 查看完整追踪
- docker container logs containerid
- docker container commands…
dockerfile实战2
- stress工具
- apt-get install stress
- 测试主机 或者容器资源(内存、cpu等)
- 每个docker启动的时候都可以限制cpu 内存等1234567FROM UBUNTURUN apt-get update && apt-get install -y stressENTRYPOINT ["usr/bin/stress"]CMD## 运行docker run -it yaxiaomu/ubuntu_stress --vm 1 --verbose
容器的资源限制
- 物理机-虚拟机之间的资源配置 virtualbox
- -m 限制memory swap memory
- -c cpu shares relate weight,相对两倍权重
- docker run –cpu-shares=5 –name=test2 –cpu1
- docker run –cpu-shares=10 –name=test3 –cpu1
- control groups,分层layer通过union file system实现