docker
介绍
docker容器总是运行在linux内核上,如果宿主机非linux系统,则会有一个linux虚拟机,所有容器运行在那个虚拟机中,所有的容器共享宿主机或虚拟机
Docker containers always run on a Linux kernel (except for the case of native Windows containers).
On a non-Linux system (e.g., a Mac) there is a Linux virtual machine, and containers always run on that VM.
All containers share that “host” or VM kernel (and by default are prohibited from making changes that would affect the whole system).
mac上的docker使用到了 HyperKit【进程名:com.docker.hyperkit】 来实现虚拟化
HyperKit is a toolkit for embedding hypervisor capabilities in your application. It includes a complete hypervisor, based on xhyve/bhyve, which is optimized for lightweight virtual machines and container deployment.
It is designed to be interfaced with higher-level components such as the VPNKit and DataKit. HyperKit currently only supports macOS using the Hypervisor.framework. It is a core component of Docker Desktop for Mac.
一次封装,到处运行
仓库:存放镜像的地方,dockerhub
镜像:容器的模板
容器:
镜像的实例就是容器(模板)
每个容器相互隔离
可以看做是一个简易版的linux环境(包括 用户权限,进程空间,用户空间,网络空间)和运行在其中的应用程序。
集装箱:容器
鲸鱼:docker
linux 容器:linux containers, LXC
容器与虚拟机不同,不需要捆绑一套操作系统,只需要软件工作需要的库资源和设置
虚拟机:
hypervisor 硬件虚拟化,需要单独的操作系统
docker:
操作系统层虚拟化(容器),直接利用宿主机内核
容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件,因此容器更具有便携性、高效地利用服务器。
操作系统层虚拟:
亦称容器化
可以实现软件的即时迁移(Live migration),使一个软件容器中的实例,即时移动到另一个操作系统下,再重新运行起来。但是在这种技术下,软件即时迁移,只能在同样的操作系统下进行。
由于在同一台服务器上的容器实例共享同一个系统内核,因此在运行上不会存在实例与主机操作系统争夺RAM的问题发生,从而能够保证实例的性能
hypervisor vs container
命令
docker run hello-world
docker version
docker info
docker --help
docker images --help
docker images 本地镜像
docker images -a 本地镜像,包含镜像的中间层
docker search -s 30 --no-trunc tomcat 星超过30的
docker pull tomcat =>docker pull tomcat:lastst
docker rmi -f image1 image2:lastst 不加tag默认最新
docker rmi -f $(docker images -qa) 删除所有镜像
docker run --name="容器名字" -it centos(镜像名称) 交互式启动
docker start -ia 2ea90f309a16 重新进入exit的容器
--name="容器新名字": 为容器指定一个名称,不指定随机生成
-d: 后台运行容器,并返回容器ID,也即启动守护式容器;
-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-P: 随机端口映射;
-p: 指定端口映射,有以下四种格式
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
exit:容器停止并退出
ctrl+p+q:容器不停止退出
docker start xx
docker kill/stop xx
docker rm -f $(docker ps -a -q) docker ps -a -q |xargs docker rm //删除多个容器
docker run -d centos 后台式启动
docker ps --no-trunc 正在运行
-a 所有
-l 最近一次
-n 2 指定最近次数
docker容器后台运行,必须有一个前台进程,解决方式,将你要运行的程序以前台进程的形式运行
docker logs -t -f --tail 10 3bcfb8b57a88
-t 打印时间
-f 追加
--tail 最近条数
docker inspect 3bcfb8b57a88 查看容器内部细节
#会启动新进程
docker exec -it 3bcfb8b57a88 ls -al
docker exec -it 3bcfb8b57a88 ls /bin/sh
#不启动新进程
docker attach xxx
docker cp 3fa4e2af10c6:/tmp/ /tmp/a 拷贝文件到宿主机
端口映射
docker run -it -p 8888(主机端口):8080(docker端口) tomcat
制作新镜像
docker commit 提交容器副本使其成为一个新的镜像
docker commit -m"提交信息" containerId
commit -a'jksong' -m"tomcat_new" 2e78acdfa04c jksong/tomcat:1.0
镜像
#brew镜像 https://mirror.tuna.tsinghua.edu.cn/help/homebrew/ git -C "$(brew --repo homebrew/core)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git git -C "$(brew --repo homebrew/cask)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask.git git -C "$(brew --repo homebrew/cask-fonts)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask-fonts.git git -C "$(brew --repo homebrew/cask-drivers)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask-drivers.git
UnionFS
联合文件系统
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,
同时可以将不同目录挂载到同一个虚拟文件系统下,从外面看只来只有一个文件系统
优点:可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。
实现包括:Unionfs、overlayfs 等
容器中可以看到联合文件系统的挂载信息
[root@3518f71fa1be /]# mount | grep overlay overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/GIYDACBQJBC22TWQIXWRXLAF6M:/var/lib/docker/overlay2/l/WQC5NRIAGOTFXFXEYUWMWK3L6W,upperdir=/var/lib/docker/overlay2/5ba3f6c1e682b5568ea80763b909af1a66ddd278917ada03b19c37066011c253/diff,workdir=/var/lib/docker/overlay2/5ba3f6c1e682b5568ea80763b909af1a66ddd278917ada03b19c37066011c253/work) [root@3518f71fa1be /]#
容器目录
#容器目录
/var/lib/docker/containers
镜像:
轻量级,可独立执行的软件包,用来打包软件运行环境和基于运行环境开发的软件,包括代码、运行库、环境变量、配置文件。
镜像都是只读的
该镜像是一个空的镜像【没有任何内容,只能执行静态编译的命令】,可以用于构建 busybox 等超小镜像,可以说是真正的从零开始构建属于自己的镜像
FROM scratch专门用于构建最小镜像,直接pull会报以下错误,scratch是一个保留名称
数据卷
卷就是目录或文件,存在一个或多个容器中,由docker挂载到容器但不属于联合文件系统
解决:容器删除后数据丢失
目的:数据持久化,容器间共享数据
特点:
卷中的更改可以立刻生效
卷的更改不包含在镜像中
卷的生命周期一直持续到没有容器使用它为止
docker run -it -v /tmp/dataVolumeHost(宿主机):/dataVolumeContainer(容器) centos 目录不存在则自动创建
docker run -it -v /tmp/dataVolumeHost:/dataVolumeContainer:ro centos 容器中只读权限
docker inspect containerId 查看 Mounts 部分
"Mounts": [ { "Type": "bind", "Source": "/tmp/dataVolumeHost", "Destination": "/dataVolumeContainer", "Mode": "", "RW": true, "Propagation": "rprivate" } ],
DockerFile方式添加数据卷
FROM centos VOLUME ["/home/a1", "/home/a2"] CMD echo "finish !!!" CMD /bin/bash
执行:docker build -f DockerFile -t jksong/centos .
最后的点指上下文,复制文件时的基础路径
Sending build context to Docker daemon 3.072kB Step 1/4 : FROM centos ---> 831691599b88 Step 2/4 : VOLUME ["/home/a1", "/home/a2"] ---> Running in 6f9aee88d976 Removing intermediate container 6f9aee88d976 ---> 95139e78ccd1 Step 3/4 : CMD echo "finish !!!" ---> Running in dac63aeb2f41 Removing intermediate container dac63aeb2f41 ---> 4f31a5c7e4ec Step 4/4 : CMD /bin/bash ---> Running in 13a869370270 Removing intermediate container 13a869370270 ---> 47d00a1db4f1 Successfully built 47d00a1db4f1 Successfully tagged jksong/centos:latest localhost:docker siqi$ vi DockerFile localhost:docker siqi$ docker build -f DockerFile -t jksong/centos .
docker inspect containerId 查看挂载到宿主机的目录
"Mounts": [ { "Type": "volume", "Name": "c5b0f479fdd1d766adbafe48ea7fecc283863c7d7b16b7c10455e6283c23398e",
#对应宿主机目录 "Source": "/var/lib/docker/volumes/c5b0f479fdd1d766adbafe48ea7fecc283863c7d7b16b7c10455e6283c23398e/_data", "Destination": "/home/a1", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "e2ab59513e9408c5a34ef9c4b1964d55bd2fdba70ffc49e71927e0d5f9867a1d", "Source": "/var/lib/docker/volumes/e2ab59513e9408c5a34ef9c4b1964d55bd2fdba70ffc49e71927e0d5f9867a1d/_data", "Destination": "/home/a2", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ]
注意:
mac下的docker不同于linux下的docker,查看宿主机方式为:
#登陆虚拟机
screen ~/Library/Containers/com.docker.docker/Data/vms/0/ttyls -l /var/lib/docker/volumes/c5b0f479fdd1d766adbafe48ea7fecc283863c7d7b16b7c10455e6283c23398e/_data
docker volume ls 查看卷列表
docker volume inspect portainer_data 查看卷信息
数据卷容器:容器之间共享数据,继承上一个容器的数据卷
run -it --volumes-from b43e9b554470 centos
Dockerfile
dockerfile是用来构建docker镜像的构建文件,dockerfile->docker build->docker run
FROM scratch #基础镜像 ADD centos-7-x86_64-docker.tar.xz / LABEL \ org.label-schema.schema-version="1.0" \ org.label-schema.name="CentOS Base Image" \ org.label-schema.vendor="CentOS" \ org.label-schema.license="GPLv2" \ org.label-schema.build-date="20200504" \ org.opencontainers.image.title="CentOS Base Image" \ org.opencontainers.image.vendor="CentOS" \ org.opencontainers.image.licenses="GPL-2.0-only" \ org.opencontainers.image.created="2020-05-04 00:00:00+01:00" CMD ["/bin/bash"] #默认执行命令
每条指令都会创建一个新的镜像,并对镜像进行提交
执行流程:
1、docker从基础镜像运行一个容器
2、执行每一条指令并对容器作出修改,类似commit操作提交一个新镜像
3、基于提交的镜像运行一个容器
4、执行下一个命令,直到所有命令执行完成
保留字:
CMD\ENTRYPOINT
相同:指定容器启动指令,多个只有最后一个生效(build镜像时都会执行)
不同:CMD可以被docker run之后指定的指令覆盖,ENTRYPOINT 会被指定的指令追加
EXPOSE 仅仅是暴露一个端口,一个标识,在没有定义任何端口映射时,外部是无法访问到容器提供的服务。
手动搭建Tomcat环境, DockerFile(默认文件名不用加-f参数)
FROM centos MAINTAINER zzyy<zzyybs@126.com> #把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下 COPY c.txt /usr/local/cincontainer.txt #把java与tomcat添加到容器中 ADD jdk-8u171-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.8.tar.gz /usr/local/ #安装vim编辑器 RUN yum -y install vim #设置工作访问时候的WORKDIR路径,登录落脚点 ENV MYPATH /usr/local WORKDIR $MYPATH #配置java与tomcat环境变量 ENV JAVA_HOME /usr/local/jdk1.8.0_171 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8 ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin #容器运行时监听的端口 EXPOSE 8080 #启动时运行tomcat # ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh" ] # CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"] CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out
registry
手写 docker hello world
官方 hello-world 描述
1. 创建 dockerFile 文件 , 文件名:scratch_test
FROM scratch COPY hello / CMD ["/hello"]
2. 编译hello程序
#include <sys/syscall.h> #include <unistd.h> const char message[] = "jksong\n"; int main() { //write(1, message, sizeof(message) - 1); syscall(SYS_write, STDOUT_FILENO, message, sizeof(message) - 1); //_exit(0); //syscall(SYS_exit, 0); return 0; }
3. 编译hell命令
#注意 需要静态编译,因为镜像中没有动态链接库,否则会报错:standard_init_linux.go:211: exec user process caused "exec format error"
#gcc默认为动态编译 gcc -o hello -static hello.c
如果报错 /usr/bin/ld: cannot find -lc 需要安装静态库文件
#How do I install static versions of glibc on CentOS 8 #centos8默认包管理器为dnf(用来替代yum) 如果没有 config-manager 命令可以手动开启,vi /etc/yum.repos.d/CentOS-PowerTools.repo , enabled=1 dnf config-manager --enable PowerTools dnf install glibc-static
也可以在 docker centos中编译
docker run -it centos yum install gcc #centos8默认包管理器为dnf(用来替代yum) 如果没有 config-manager 命令可以手动开启,/etc/yum.repos.d/CentOS-PowerTools.repo , enabled=1 dnf install glibc-static gcc -o hello -static hello.c
将编译好的hello命令放到跟 scratch_test 同级目录
3、生成镜像,启动容器
#生成镜像
docker build -f scratch_test -t jksong/centos .
#启动容器 docker run jksong/scratch1.0
bogon:docker siqi$ docker image history jksong/scratch1.0 IMAGE CREATED CREATED BY SIZE COMMENT bc211bb97db9 47 minutes ago /bin/sh -c #(nop) CMD ["/hello"] 0B 0b26ba08bcac 47 minutes ago /bin/sh -c #(nop) COPY file:a8e1794d4f8b5947… 1.19MB
看到输出则表示成功
docker build 时输出调试信息
注意都需要禁用缓存 #方式一 禁用buildkit export DOCKER_BUILDKIT=0 docker build -f DockerFile -t jksong-test:1.0 . --no-cache #方式二 --progress string Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto") docker build -f DockerFile -t jksong-test:1.0 . --progress=plain --no-cache
图形管理界面
portainer/portainer-ce
docker pull portainer/portainer-ce docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
访问地址:http://127.0.0.1:9000/#!/auth
私服
docker run -d -p 5000:5000 --restart=always -v /opt/data/registry:/var/lib/registry --name registry registry #来标记一个镜像 docker tag traefik:v2.0 127.0.0.1:5000/traefik:v2.1 #上传 docker push 127.0.0.1:5000/traefik:v2.1 #查看私服镜像 http://127.0.0.1:5000/v2/_catalog http://127.0.0.1:5000/v2/traefik/tags/list
参考:
https://docs.docker.com/registry/deploying/
https://yeasy.gitbook.io/docker_practice/repository/registry
参考:
Hypervisor(硬件虚拟化)
LXC,其名称来自Linux软件容器(Linux Containers)
Add libraries for static compilation CentOS 8
Inside Docker's "FROM scratch"