docker技术原理和操作实践

容器有自己的主机名和域名(UTS),文件系统(mount),IPC, PID, USER, Net

在内核中创建出多个名称空间,每个名称空间拥有自己的独立的主机名和域名,文件系统,IPC, PID, USER, Net

Linux内核引入namespaces,容器即是基于namespaces实现的。





这就是容器级虚拟化,所有容器工作于同一个内核中,内核可对容器内进程实行资源分配,靠的是Control Groups技术,简称cgroups



LinuX Container LXC):

lxc-create+template

Docker相当于LXC的简化使用版

用户空间所需要的所有文件编排好打包成一个文件称为镜像文件,此些文件可放置于仓库,需要时取之。当你创建容器的时候,就到仓库里拉取镜像文件,基于镜像文件创建容器,简化了容器的使用难度

 

一个容器只运行一个进程的思路。

 

镜像构建:镜像文件分层构建,联合使用,容器里的程序的配置文件可以存放于外部。镜像文件一般都是只读的。

 

容器编排工具:machine+swam+composekubernetes

 

Docker社区版改名Moby

 

相关类库libcontainer  runC(容器引擎)

 

OCIOpen Container Initiative)包含运行时标准和镜像格式标准

OCFOpen Container Format):runC就是该格式的实现

存放容器镜像的网站  https://hub.docker.com/

 

 

 

 

Docker架构图:



Docker daemon支持ipv4+端口,ipv6+端口,unix socket通信

Docker架构有3部分组成:docker daemon, docker client, docker registries(仓库)

关于仓库:仓库里有各应用程序小仓库,比如nginx小仓库里只有各个不同版本的nginx镜像,各个不同版本的nginx镜像使用 标签(tag) 标识,比如nginx:1.10,  nginx:latest, nginx:stable等等

可以建立自己的私有仓库

 

镜像和容器的关系类似于程序和进程的关系,所以容器有生命周期。

 

Docker的对象:镜像,容器,网络,存储卷(volumes),plugins等等统称为Docker的对象。

 

Docker的依赖基础环境:

164cpu

2linux kernel 3.10+

3linux内核支持cgroupsnamespaces

 

安装过程如下:

yum erase podman buildah 卸载podmanbuildah

yum install -y yum-utils   安装yum-utils 

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 添加阿里云的docker-ce仓库

yum makecache 更新软件包索引

yum install docker-ce  安装docker-ce 社区版

docker version  检查是否安装成功

systemctl start docker 启动docker

systemctl enable docker 开机启动

 

docker镜像加速:

mkdir -pv /etc/docker

tee /etc/docker/daemon.json <<-'EOF'

{

  "registry-mirrors": [

    "https://dockerhub.azk8s.cn",

    "https://docker.mirrors.ustc.edu.cn",

    "https://hub-mirror.c.163.com"

  ]

}EOF

 

docker  COMMAND --help 查看帮助信息,COMMAND表示子命令

 

docker常用命令



 

docker image pull nginx:alpine   从仓库拉取镜像

docker image ls  列出镜像

docker image ls --help  查看更多帮助

 

docker container --help  

镜像创建的时候有默认的执行命令

 

docker run --help   启动一个容器

docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 

docker run -it --name busybox_1  busybox

docker run  --name web1 -d nginx:stable-alpine  启动nginx服务,本地没有该镜像会自动去镜像仓库拉取

docker ps   列出启动的容器

docker ps -a  列出所有的容器

docker run --name  kvstor1 -d  redis:latest  启动redis服务

docker exec -it kvstor1 /bin/sh  kvstor1服务交互

docker logs kvstor1  获取容器kvstor1的日志

 

关于Docker镜像:

 




用于支持联合挂载的文件系统:Aufsoverlayfsbtrfsdevicemapper

 




镜像的存储位置:Registry

 


Docker Registry分类:

 




Docker Registry包含两部分repoindx

 


 

Docker hub提供的特性有:

 


docker pull <registry>[:port]/[<namespace>/]<name>:<tag>

 

镜像的生成方法有3种:

dockerfile,基于容器制作和Docker Hub automated builds(配合gitgithub

 

基于容器制作镜像的方法:其实就是基于容器的可写层

 


docker commit quirky_leakey  busyboxpp:v1.0 基于容器quirky_leakey创建镜像

docker tag busyboxpp:v1.0  qinghe/busyboxpp:latest  给镜像打标签

 

docker客户端登录时使用的用户名为阿里云账户全名,密码为当前设置的密码jm6688mfc  lqingheno.1@gmail.com  jm6688mfc

 

 

1. 登录阿里云Docker Registry

$ docker login --username=lqingheno.1@gmail.com registry.cn-hangzhou.aliyuncs.com

用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。密码jm6688mfc

您可以在访问凭证页面修改凭证密码。

2. Registry中拉取镜像

$ docker pull registry.cn-hangzhou.aliyuncs.com/qinghe/busyboxpp:[镜像版本号]

3. 将镜像推送到Registry

$ docker login --username=lqing******@gmail.com registry.cn-hangzhou.aliyuncs.com

$ docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/qinghe/busyboxpp:[镜像版本号] 

$ docker push registry.cn-hangzhou.aliyuncs.com/qinghe/busyboxpp:[镜像版本号]

请根据实际镜像信息替换示例中的[ImageId][镜像版本号]参数。

 

 

镜像的导入和导出:

docker save -o my_images.gz nginx:stable-alpine  redis:latest  镜像保存为my_images.gz

 

docker虚拟化网络:

docker network ls  支持bridgehost none

 

bridge(默认)

docker0设备是docker虚拟出来的软交换机。当创建一个容器的时候,就随同一起创建2个网卡设备,一个在插在该容器上,一个插在该软交换机上,就相当于该容器连接到了该软交换机上。在docker宿主机上执行ifconfig可以看见插在docker0设备上的网卡设备(yum install bridge-utils && brctl show 命令可查看)。

 

docker0设备既可以当作交换机,当赋予IP地址也可以当作网卡设备。



图解:web1web2web2表示容器,容器连接的表示docker0交换机,交换机下面表示物理机器,外部的客户端要访问容器中提供的服务,只能通过物理机器的DNAT

 

 

Overlay network 叠加网络:使用ip隧道

 

Host

每个容器具有独立的UserMountPIDUTSNetIPC。现在让每个容器有自己独立的UserMountPID,但是它们公用同一组UTSNetIPC

 

Docker网络模型总结:

 


docker inspect --help

docker inspect bridge

docker inspect host

docker inspect none

docker inspect  web1   inspect可以查看任何docker对象的详细信息

 

 

 

docker run --rm --network none busybox:latest ifconfig -a  指定为无网络的容器



docker run命令中 --add-host, --dns, --hostname 选项的使用

--dns 设置dns服务器,--hostname设置主机名, --add-host添加主机àip条目

 


容器暴露:

 


 

将容器端口映射到宿主机的指定的IP和端口上,然后访问宿主机的IP和端口就可以访问到该容器提供的服务。

docker run --name myweb -p 192.168.32.130:80:80 nginx:stable-alpine





查看如上创建的容器myweb提供的端口:docker port myweb

表示该容器的80端口映射到了192.168.32.130:80



其实是在宿主机上添加了DNAT的防火墙规则:iptables -t nat -vnL

 


 



 

docker run --name web -d -it --rm -p 2222 busybox:latest /bin/httpd -p 2222 -f

docker run -it --rm --net container:web --name joined busybox:latest netstat -tan

joined容器共享了web容器的网络名称空间

 


 

 

docker network create -d bridge --subnet '172.88.0.0/16' mybr0 创建mybr0交换机

docker network ls

docker run -it --name bb2 --network mybr0 busybox:latest  ifconfig

docker存储卷 volumn



总结一句话:将容器的存储数据保存在外部

 





 

 

 

 






 

 

基于容器(docker commit命令)制作镜像

通过dockerfile制作镜像:制作符合自己需求的镜像

Dockerfile是构建docker image的源代码,就是用于构建镜像的命令保存的文本文档。

Dockerfile语法格式:如下

# 表示注释

INSTRUCTION arguments 

指令不区分大小写,但是约定俗成一般大写,指令按顺序执行,第一条指令必须是`FROM`指令,表示基于哪个基础镜像制作。(docker build命令)

Docker build时是可以使用环境变量的,因为Docker build过程中要先基于基础镜像启动容器,此时可以向容器中注入环境变量

 


 

MAINTAINER指令已经废弃:使用LABEL指令替换

 




 

指定镜像的存储卷:



 

可以在镜像中直接指定要暴露的端口:

基于该镜像生成容器的时候(docker run -P 要有-P选项才会暴露),会映射至宿主机的所有地址,端口是动态的端口

 

 

 

 


RUN指定在docker build过程中运行的命令:

 


 

 

 

CMD指令表示镜像启动为容器时要被执行的默认命令

 


例子:

mkdir -pv  /data/img2  创建目录/data/img2

cd   /data/img2

vim Dockerfile    创建Dockerfile文件,写入如下内容:

FROM  busybox:latest

LABEL maintainer="MageEdu  <mage@magedu.com>"  app="httpd"

ENV WEB_DOC_ROOT="/data/web/html/"

RUN mkdir -p $WEB_DOC_ROOT &&  \

         echo "<h1>Busybox httpd server.</h1>" > ${WEB_DOC_ROOT}/index.html

CMD /bin/httpd -f -h ${WEB_DOC_ROOT} 

#另外的写法CMD ["/bin/sh","-c","/bin/httpd -f -h ${WEB_DOC_ROOT}"]

 

docker build   -t  tinyhttpd:v0.2-1 ./    基于上面Dockerfile文件做镜像tinyhttpd:v0.2-1

 

docker image inspect tinyhttpd:v0.2-1   查看镜像tinyhttpd:v0.2-1的信息

 

docker run --name tinyweb2 -it --rm  -P tinyhttpd:v0.2-1   基于镜像tinyhttpd:v0.2-1运行容器

 

docker exec -it tinyweb2  /bin/sh   进入镜像里面

 




 


 

 

例子:

mkdir -pv img3

cd img3

vim Dockerfile

FROM nginx:stable-alpine

LABEL maintainer="mageedu"

ENV NGX_DOC_ROOT="/data/web/html"

ADD  entrypoint.sh  /bin/

CMD ["/usr/sbin/nginx", "-g", "daemon off;"]  #CMDENTRYPOINT提供parm

ENTRYPOINT ["/bin/entrypoint.sh"]

 

 

vim entrypoint.sh

#!/bin/sh

cat > /etc/nginx/conf.d/www.conf  << EOF

server {

       server_name $HOSTNAME;

       listen ${IP:-0.0.0.0}:${PORT:-80};

       root ${NGX_DOC_ROOT:-/usr/share/nginx/html};

}

EOF

exec "$@"

chmod +x entrypoint.sh   赋予执行权限

docker build -t myweb:v0.1  ./   构建成镜像myweb:v0.1

docker run --name web14  myweb:v0.1   基于该镜像生成容器

docker exec -it  web14   /bin/sh   进入该镜像

 


 

 

 

对容器中主进程的状态监测:

 


 


 

 

 

STOPSIGNAL指令定义容器接收的用于退出的信号:

 


 

 

 

 

ARG指令用于在docker build时传递变量:

 


 


 

 

 

 

 

 

 

构建私有的docker registry

 


Harbor项目:





Harbor的特性:



Docker compose:定义多个容器,管理编排容器的工具

 

Harbor依赖于Docker compose

 


评论

此博客中的热门博文

OAuth 2教程

网格策略

apt-get详细使用