Docker principle and

  

Virtualization system:
  1. Type the I-: this is virtualization Hypervisor runs directly on the hardware, to create a virtual machine.
  2. Type-II: This virtualization is similar to VMware Workstations.

  

  IPC: In the process of the same name space can be achieved through inter-process communication IPC.
  PID: each name must be in space a process with process ID 1, which is the parent of all processes, namely the init process, so to achieve user isolation space, we need to let each user space process, thought he was . init process runs under the
  user: let the progress of each user space think they are running on separate hosts, it must be implemented in each user space is both a UID 0 user, but the user in the real system, but it is a normal user.

Virtual containers:
 resource limitations:
  Typically, there are two, one is able to use the percentage elastic limit percentage of the total resources of the other is a summary resource constraints.

 Realize resource limit is Cgroups (Control Groups):
  1. blkio: Block devices the IO
  2. CPU: the CPU
  3. cpuacct: the CPU resource usage reports
  4. cpuset: CPU set on multi-processor platforms
  5. devices: access devices
  6. freezer: suspending or resuming a task
  7. memory: memory usage and reporting
  8. perf_event: cgroup tasks for unified performance test
  9. net_cls: data packet cgroup tasks created class identifier.


Docker, LXC, CNCF:
  Docker container technology is developed by a commercial company, is a container early the kernel is based on LXC (LinuX container), to achieve the creation and management of the container.
  LXC: There is a technique called early jail (prison, or called sandbox), a technique that allows an application to run in a sandbox, regardless of the application to make any damage to the system will not affect the real system, just sandbox virtual environment. Later this technology is also introduced in Linux, called vserver, which is now more familiar chroot function. But in the Linux system early kernel support namespace, is the need to write code by themselves, calling the system call to create a UTS, Network, IPC, and so different name space, combined with a chroot create a user space on one operating system, but for ordinary users, it is very difficult, and LXC provides a set of tools, will integrate these functions into a tool, if users need to create a container, just use lxc-create and other command-line tool, you can easily create containers, but when you create LXC container, it needs the help of template (template), while allowing lxc-create to create a container, you can be on the CentOS system, create a container Ubuntu or FreeBSD and other containers , can only provide you with the appropriate template and packages should be installed to these systems; but the problems caused by the use LXC this way is still very difficult, not easy to create application templates, and also created a lot of redundancy More than data; such as: I want to create two containers Ubuntu, I need to install two copies of the same data; and if I need a container
Migrated to another host, how do? LXC does not provide the appropriate tools. So it is not suitable for large-scale use. Docker: It is early kernel creates containers LXC, but it uses more efficient than LXC, a more sophisticated way to create a container, it is not to install the container using a template, but will produce a mirror image of the container, when the container is required, to make a good image before downloading directly from a local mirror warehouse, container can be started directly. And its mirror image overlay uses a technique called data redundancy way to solve the problem, in fact it uses something called three-way mirror overlay to achieve efficient use of data stored in the container and private data. By means of shared storage container to the private data stored in an external host when the host goes down, as long as the download mirrors on the new host, start the container, you can mount the data recovery services. Specific as shown below:
  Note:
   Docker order to facilitate the management of the container, which defines a container can only run one process, but in fact similar container with a virtual machine, it can run multiple processes, but for the convenience of management, limiting container only run a process.

    

 

This technology brings the benefits of containers:
  For developers, is a big advantage, because of the emergence of a real solution Docker code for write once run everywhere, no matter what the underlying system, as long as the run docker, after the mirror to do, directly choreography is good, then you can start a container on the host. For operation and maintenance personnel, the problem is caused by, more complex system architecture, the way the original commissioning process, the container era becomes extremely difficult, because the container is likely not the various debugging tools.

Question on the container deployment:
  The construct of the NMP environment, we usually need to deploy MySQL container, followed by PHP container, and finally Nginx container, in this order you will require to make the environment are working properly, or Nginx proxy PHP server may appear, the results can not find the PHP server, because the container starts, will change its IP address, that IP assigned by DHCP MAC do not be fixed in accordance with? But in fact is not possible, because the container is not fixed MAC, its card is virtual, are two virtual NICs through the "virtual cable" on Linux was created, one end of the access container, one end of the access Docker0 (default bridge ) bridge, thus achieving a container vessel after the completion of startup can access the network, so each time the container is started, it is impossible to know the MAC address of the virtual network card this time is the number of creation, it is necessary to use other methods to obtain the IP address, which is why the container needs to arrange for LNMP environment, Nginx PHP to rely, as it sought to represent PHP, MySQL and PHP are also dependent, to obtain data because PHP applications from MySQL, so you must start MySQL container, so as to obtain the IP MySQL containers currently in use, then start PHP container, the container is passed to the IP MySQL PHP container, so the container can tell MySQL PHP's IP, and Nginx, too, after this arrangement, LNMP environment each vessel will be able to obtain it depends container IP, you can communicate a.

In order to solve the problem of the order to deploy container, container technology, it must be combined with orchestration tools used together to achieve large-scale application.
Currently more well-known layout tools:
  Docker: machine + swarm + compose, with the use of these three tools to achieve choreography.
  Scheduling tools provided by third parties: Marathon mesos +
  Google: Kubernetes -> short K8S

libcontainer:
  also known as RunC, which is the core program of official Docker Docker build new vessels, due LXC in function, not with the times Therefore Docker official, finally decided to develop a new container to build the core, it is runC.

Docker, Moby, CNCF historical stories:
  Docker we know that it is a commercial company, early Docker first appeared, the sensation in the world, in order to allow Docker technology to have greater development, Docker their products into the open source community version and commercial version, but Docker commercial version never able to trust activities bigwigs on business, we did not get much financing, but the open source community edition does not always hot, Docker in order to get more business interests, it will eventually decided to community version of Docker renamed Moby , hoping to attract more attention to the concerns of its commercial version, but it did not. At a time when Google finds himself secretly using container technology more than a decade is now being Docker to open source, but also the development of so prosperous, well known, but Google does not want to fall into the hands of the right to speak Docker container technology, which determines to support a small container company, but the company's products in the Google strongly support, it is still fallen off, not Docker opponent, finally, Google found Docker in the development layout tools, good no contribution, while he has over ten years container experience (Google inside a container called Borg (Borg)), and therefore organized the engineers developed Kubernetes, and in view of Docker company for commercial purposes, free to change Docker community Edition, change the nature of Docker's, Google will donate Kubernetes to the CNCF, while the container is CNCF Standards Foundation organization, it is Google co several
well-known companies such as: IBM, Microsoft, Facebook, etc. set up a joint organization. Around the world will not stand for the development process Kubernetes, plus Kubernetes its birth is standing on the shoulders of Bong established, so it was released to become the target of the world's focus, just three years, it has grown from 0.1 to version 1.1 to version 4 iterations per year, up to 2018, its market share of more than% 80.


OCI (Open container Initiative):
  it is led by the Linux Foundation, founded in June 2015, are in the surrounding container format and run developing an open industry standard.
  It has developed two standard specifications:
    1. Run-time standard (at The Runtime Specifications (Runtime-spec))
    2. standard image formats (at The Image Specification (Image-spec))

OCF (Open Container the Format):
  OCF is an open container format produced under standard OCI advocacy.

Docker's basic architecture:

  

  Note:
 Docker's Mirror:
   Registry: Docker called in the warehouse in the mirror, the mirror Docker yum repository is somewhat similar to the source repository, but it is organized like this:
    Docker mirroring the official address of the warehouse: hup.docker.org, of course, the country will also have a lot of docker mirror sites.
    organizational format Docker image warehouse are:
      application name: the version number
      where: application called warehouse name.
      the version number: for the warehouse image name is also its tag tag number
    to Nginx as Example:
      Nginx: the warehouse name.
      . while a mirror may have multiple names 1.15 this is a mirror image name,: nginx
        for example: 1.15 is the latest release of Nginx, it will also give it a name: nginx: lasted namely the latest version,
        the name will be released with the latest version of Nginx is changed.
      nginx: 1.14 In addition, we know, Nginx release, the second number is even said that this version is stable version,
        is an odd version was developed, so this version will usually have a name: nginx: stated that is stable version . nginx mirror

  docker download site are many:
    the use of Tsinghua University repo warehouse, after downloading its repo file also need to modify its repo mirror site to mirror sites Tsinghua University.
      yum install docker-ce

    After installing the docker, docker to download the image, can be used to download the domestic mirror Accelerator: use:
    mkdir / etc / docker
    Vim /etc/docker/daemon.json
      { "Registry-Mirrors": [ "HTTPS: // registry.docker-cn.com "]}

  View version information docker:
    docker version
    docker info

  common operations of docker:
    docker Search: Search docker mirror repository specify a mirror name.
    docker pull: Specifies the image to download a local.
    docker ImagesRF Royalty Free: column the existing local mirror

  download mirror docker:
    docker pull nginx Image: Alpine-1.14
    Note: alpine: this is a small release of nginx, it is only the size of a small integrated nginx necessary to run the environment, nothing else. If you need some debugging tools, it is not for you.
      In addition, mirroring the general official release, they are generally rarely with debugging tools.
      Another note: We search docker mirror, you will see similar tom / nginx kind of mirror, which is a tom this person, registered in the docker official account, upload the image to produce their own nginx.

    Docker pull busybox

    . docker imgle ls --help # view help ls subcommand
    docker imgle --help

  create a container:
    Docker Container # create the Create only container, but do not run.
    Docker Container RUN # create the container, and run.
    docker container start # start already created one or more containers.
    docker container stop | kill # can be parked in one or more containers.
    Docker Top Container # view those containers are consuming the most resources.

  Docker Container RUN [Options] Image [the Command] [parameters ...]
   Options:
    -t: boot image when, to add a terminal access interface, in order to be able to start after the connection log in.
    -i: start as an interactive mode.
    --rm: after the stop, delete the container.
    -d: run to the background.
    --name <ImangeName >: to start a container name a name.
    --network <NetName>:. the vessel was charged with a specified network

  docker network ls # list the current native how many networks are available.
  ifconfig can view, when the docker installed, it automatically creates a docker0 the bridge, the bridge is a NAT bridge.
       It is a bridge directly on the physical NIC, and the physical network can directly communicate.

  Example:
   Docker pull busybox busybox # Download a mirror of.
   Docker Container RUN -it --name b1 busybox: Latest # This starts a container called b1,.
    / # Ps-# This starts busybox, it is currently displayed sh of the terminal.
    / #mkdir / Data / httpd
    / #vim /data/httpd/index.html
    / #httpd -H -f / Data / httpd # busybox start a httpd process, the web and indicates its root.
    / #exit # sh implementation of exit withdrew from the terminal, will cease container

  terminal 2:
    Docker PS
    Docker the Inspect b1 b1 # to view details of this vessel.
    curl http://1.1.1.1/ # so that you can access the container the httpd served.

    docker ps -a # view of the container to stop.

  Example 2:
    Terminal 1:
      docker start -a -i b1 # restart the container b1 stop

    terminal 2:
      Docker PS
      .. the kill Docker # b1 b1 container can be forced to close under normal circumstances should be used stop, can protect the data is not lost
      docker rm b1 # delete stop container b1

  example. 3:
    Docker rUN --name nginx1 Nginx -d: # 1.14 Alpine-function, if present access to the Internet, there may be run directly, Docker automatically download the image.
    Note:
        run the application in a container, it must operate in the foreground, otherwise the container has been started will be closed, because the container is only one process, which is the framework supporting the container
    Docker PS

    Docker RUN --name redis1 -d redis: 4-Alpine # redis start a container, it will automatically download the image . and start.

  example. 4:
    Docker Exec Expediting iT redis1 / bin / # SH run on a command specified container redis1, / bin / sh, and use the interactive logon.
    / Data # # PS thus can log in to this container redis1 on.

    Docker container logs nginx1 # nginx1 view log information.

Docker All state conversions schematically

  

  Docker's image:

  

    Docker镜像包含了启动容器所需的文件系统及其内容,因此它用于创建并启动docker容器.
  docker镜像采用分层构建的机制,最底层为bootfs,其上为rootfs.
  bootfs: 用于系统引导文件系统,包括bootloader和kernel,容器启动完成后,bootfs会被卸载,以节省内存空间.
  rootfs: 它在运行中的docker容器中变现为根文件系统.
  如: docker exec -it nginx1 /bin/sh   #登录后, ls / 可以看到全部的根文件系统目录.
  传统OS:
    系统启动时,内核挂载rootfs时,为确保不会误删除文件,通常会先以只读模式挂载,完整性自检完成后,再重新以读写模式挂载rootfs.
    docker: 它在启动内核,挂载rootfs时,始终是以只读模式挂载, 而后在通过联合挂载技术额外挂载一个可写层.实现读写操作。

Docker Image Layer

  

  

  此镜像显示了Docker的镜像层级,从上到下分别为:
  可写层
  add Apache 和 add emacs(类似于vim的编辑器): 这两层为自己通过yum安装在镜像中的工具.
  Debian: 这是为安装的工具提供的基本的最小安装的根文件系统已共Apache能运行起来.这里使用的是Debian.还可以使用CentOS等.
  bootfs: 这一层则是启动Debian这个rootfs所需的bootloader和kernel,通常在将Debian启动起来后,它将自动被卸载.

Docker实现叠加挂载镜像的文件系统:
  overlayfs: 从kernel3.18以后被整合到Linux内核中了. 它叫 叠加文件系统, 再早期Docker实现叠加挂载是使用Aufs(Advanced multi-layered unification filesystem:高级多层统一文件系统), 而此文件系统是2006年开发,但因代码质量问题,一直未被整合到kernel中; 据说它的代码有3万行,而ext4这种文件系统总代码量4千多行。所以早期要使用docker有两种方式 一种手动给内核打aufs的补丁,另一种就是使用Ubuntu系统,因为它比较早的将Aufs整合到它的kernel中了。不过现在目前 CentOS系统已经能支持overlayfs的第2版了,所以可以直接使用docker即可.
  docker info
     #输出中Storage Driver: overlay2 ,overlay2是一种虚拟抽象层的文件系统,它是建构在Backing Filesystem: xfs ,即后端文件系统xfs之上的文件系统。

  docker pull quay.io/coreos/flannel:v0.10.0-amd64
     #下载quay.io 这个网站的coreos名称空间下的flannel仓库中的tag为v0.10.0-amd64 的镜像。默认docker使用https去下载. quay.io是docker镜像很有名的第三方提供者.

 示例1:
  #基于busybox创建一个测试镜像:
    docker run --name bx1 -it busybox
    / #mkdir -p /data/html
    / #vi /data/html/index.html
      <h1>Hello busybox HTTP Server</h1>

  终端2:
    docker commit -p bx1    #-p是让bx1容器先暂停,避免有人访问镜像,导致镜像创建不完成.
    docker image ls       #可看到刚创建的镜像.
    docker tag <IMAGE ID> tom/bbox:v0.1        #这样就给指定的镜像打上了tom/bbox的标签,并且tag为v0.1s
    docker tag tom/bbox:v0.1 tom/bbox:latest    #在tom/bbox:v0.1上再给其创建一个标签名.
    docker image rm tom/bbox:latest    #删除一个标签名, 它只是删除标签,就像删除硬链接,文件是不会被删除的。

 示例2:
  docker inspect nginx:v1.14    #查看其CMD,可以看到的其被docker启动后,容器中将启动的第一个进程为nginx
  docker inspect tom/bbox:latest

 示例3:
  #基于busybox制作一个启动后运行busybox中的httpd的镜像.

  终端1:
    docker run --name bx1 -it tom/bbox:latest    #注:这是基于示例1中的内容创建的.

  终端2:
    docker commit -a "tom <[email protected]>" -c ‘CMD ["/bin/httpd","-f","-h","/data/html"]’ -p bx1 tom/bbox:v0.2
    注:
      CMD: 这是仅修改启动容器后,执行什么命令, 注意CMD必须大写!! 其次参数的顺序不能乱.
      -p : 制作时让容器处于暂停状态.
            制作完成后,直接给它加一个标签名为tom/bbox:v0.2
    docker image ls  #查看制作好的镜像
    

    docker  run  --name bx2  -d  tom/bbox:v02
  终端3:
    docker inspect bx2  #查看bx2的定义,主要看CMD定义
    curl http://1.1.1.3/    #这样就可以直接访问busybox启动的微型httpd了。


  示例4:
  #上传镜像到docker hup中的仓库中.
    1. 要创建docker hup的登录账户,并登录到后台,创建一个仓库.
       如: 上面创建的镜像名为: tom/bbox:v0.1
        那创建的仓库就叫 tom/bbox
    2. 上传镜像前,要先登录
      docker login -u tom #然后要求输入密码,Login Succeeded表示登录成功.
    3. 开始上传镜像:
      docker push tom/bbox #不加tag则表示将本地所有镜像都推送上去。

  示例5:
    #导出已有镜像,并在其它主机上导入镜像:
    docker image ls
    docker save -o myimages.gz tom/bbox:v0.1 tom/bbox:v0.2    #这样即可将两个镜像打包成myimages.gz。

    #登录到另一台docker上就可以执行:
    docker load -i myimages.gz #就可以导入镜像了
    docker image ls

  示例6:
    docker exec -it --name bx1
    / #wget -O - -q http://1.1.1.2/   # 假如Nginx容器启动后的地址为1.1.1.2,则通过wget测试访问.
           -O :加载完成页面后,不保存,直接输出当标准输出."-"

Docker的四种网络模型:
  第一种是Closed Container(封闭式容器): 它主要是用来处理一些Docker计算任务的,完成后就自动退出了,因此它无需网络协议栈.
  第二种是Bridge Container(桥接式容器): 它是通过创建一根虚拟网线,一头接入容器中,也就是Container Virtual interface,另一头接在Docker bridge Virtual Interface上.
  第三种是Joined Container(联合容器): 它是让A和B两个容器都共享一组Net,UTS,IPC名称空间,这样的好处是A和B可以直接通过lo接口通信,并且还可以桥接到Docker桥上,共享网络接口。
  第四种是Open Container(开放容器): 它是第三种的扩展,它直接与物理机共享了Net,UTS,IPC名称空间,因此物理机上的网络接口它都可以看到,并且可以直接管理。

    

    示例1:
    #inspect 查看docker组件的详细信息.
    docker network ls
    docker network inspect bridge #查看bridge网络的详细信息。

  示例2:
    #创建网络模型3
    终端1:
      docker run --name bx1 -it --rm busybox
      / # wget -O - -q http://127.0.0.0.1/

    终端2:
      docker run --name bx2 -it --network container:bx1 --rm busybox
      / #echo "hello world." > /tmp/index.html
      / #httpd -f -h /tmp

  示例2:
    vim /etc/docker/daemon.json     #以下仅供参考,新版本有些参数以不支持!!
    {
      "bip": "1.1.1.1/24", #设置docker0的IP
      “fixed-cidr”:"10.20.0.0/16",
      "fixed-cidr-v6":"2001:db8::/64",
      "mtu":"1500",
      "default-gateway":"10.20.1.1",
      "default-gateway-v6":"2001:db8:dbcd::89",
      "dns":["10.20.1.2","8.8.8.8"],
      "hosts":["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"] #启动docker监听在2375端口上.
    }

    systemctl restart docker      #新版本建议直接修改启动脚本,已参数形式传入

  在主机2:
    docker -H 1.1.1.1:2375 image ls #这样就可以查看1.1.1.1这台主机上docker的是否有镜像了。

  示例3:
    #创建docker网络
    docker network create -d bridge --subnet "1.1.1.0/16" --gateway "1.1.1.1" mybr0
    docker run -it --name bx1 --net mybr0 busybox:v0.1

  示例4:
    #启动容器时传递参数:
    docker run --name t1 -it --network bridge -h t1.test.com --rm busybox:latest

    docker run --name t1 -it --network bridge -h t1.test.com --dns 114.114.114.114 --rm busybox:latest
    docker run --name t1 -it --network bridge -h t1.test.com --dns 114.114.114.114 --add-host www.test.com:1.1.1.1 --rm busybox:latest

  示例5:
    docker run --name myweb --rm -p 80 tom/bbox:v0.2 #创建一个地址映射,允许外部访问此容器.
      #注: -p 80 ,实际是创建了一条 iptables DNAT规则.
    docker port myweb #查看docker创建的端口映射

    docker run --name myweb --rm -p 1.1.1.1::80 tom/bbox:v0.2
    docker run --name myweb --rm -p 80:80 tom/bbox:v0.2
    docker run --name myweb --rm -p 1.1.1.1:80:80 tom/bbox:v0.2

Docker的数据卷(Data Volume):
  为避免关闭再重启容器,其数据不受影响,但删除Docker容器,则其更改将会全部丢失.
  存在的问题:
    1. 存储于联合文件系统中的数据,宿主机不易访问.
    2. 容器间数据共享不方便.
    3. 删除容器其数据会丢失.
  解决方案:"卷(Volume)":
    卷是容器上的一个或多个目录(即:多个卷),此类目录可绕过联合文件系统,与宿主机上的某目录绑定(即关联)

Docker有两种类型的卷:
  1. Bind mount volume(绑定挂载卷):这是有用户自定义指定docker中的某目录挂载到宿主机的某个指定目录.
  2. Docker-managed volume(docker管理的卷): 这是由docker自己维护,用户需要在/etc/docker/daemon.json中指定启用docker自动启动容器时,关联宿主机上由docker默认自动创建一个目录,并与容器中指定目录关联的方式。

  示例:
    #由docker管理的卷:
    docker run --rm --name b2 -it -v /data busybox:latest

    终端2:
    docker inspect b2   #可查看其“Mounts”段,其中有说明容器中/data 目录与宿主机上的那个目录建立的关联.
              接着可测试在宿主机上目录中创建文件,在容器中编辑,是否可行。

  示例2:
    docker run --name b2 --rm -it -v /data/volumes/b2:/data busybox:latest

    终端2:
    echo “Hello Container busybox.” >> /data/volumes/b2/index.html
      #接着在容器中查看.
      # 再尝试删除容器,再关联相同目录,查看数据是否依然可访问。

    docker inspect -f {{.Mounts}} b2    #简单过滤.
     #注:
      JSON中使用"[]": 表示这是一个列表, {}: 表示这是一个关联数组(也叫Hash映射),它可嵌套.
      在关联数组中的格式:
      {
        "Key":"Value",    #每个键 值对要使用 逗号分隔.
        "Key":"Value",
        "key0": {
          "key1":"Value1",    #key1的上层是“key0”, 而key0上层是 根(通常用"."表示.)
          ..
        },
      ..
      }

  docker inspect -f  {{.Mounts}}  b2
     #最外层{} 为引用格式, 内层{.Mounts} 为引用数组中.Mounts
      . :表示根,.Mounts:表示根下的Mounts.
  docker inspect -f {{.NetworkSettings.IPAddress}} b2 #这是简单的Go模板,go模板还支持循环,判断等.

  示例3:
   #创建一个基础容器,让其它容器共享它的UTS,IPC,Network名称空间 已经它的卷映射.
  终端1:
    docker run --name infraCon -it -v /data/volumes/b2:/data/web/html busybox
    / #ifconfig

  终端2:
    docker run --name nginx --network container:infraCon --volumes-from infraCon -it busybox
    / #ifconfig

  终端3:
    docker inspect infraCon
    docker inspect nginx    #查看“Mounts” 和 Networks是否与上面的一样。


Dockerfile:
 格式:
  # : #号开头为注释.
  FROM : 第一个指令必须是FROM,它用来指明,依据那个基础镜像做镜像。
      一般指令建议使用大写以区分参数, 但指令不区分大小写.
     格式:
      FROM <仓库名>[:<tag>] 或 FROM <仓库名>@<Hash摘要值>

  使用dockerfile制作镜像的注意事项:
   1. 必须把镜像文件都放到一个指定目录中, docker build在打包时,只打包该目录中的文件.超出此目录的文件将不会被打包到镜像中.
   2. .dockeringore : 这个隐藏文件在指定目录的中,用于设定打包时排除的文件列表,可使用通配符。
   3. docker build 在进行镜像打包时,它实际上类似于通过启动一个容器,然后,在容器中运行一些命令,创建一些文件,这些数据都保存在可写层中, 再将可写层打包到镜像中一样,不过,docker build是隐藏式启动基础镜像来自动完成这些操作,所以,需要知道你要使用某些命令,这些命令必须在基础镜像中存在才能使用。
   4. 变量替换:
    变量格式: $VarName 或 ${VarName}
    变量替换: ${VarName:-String}    #若VarName为空或未定义,则使用String做为值. 否则使用VarName的值.
          ${VarName:+String}   #若VarName有值,则使用String替换该值.
      5. dockerfile中的指令:
    1. copy <Src> <Dest> 或 COPY ["<Src>",..."<Dest>"]    #注:Src若为目录,复制时,是仅复制目录中文件,而不复制目录本身的.

  示例:
    mkdir /dockerfile/
    cd /dockerfile
    vim Dockerfile    #注: 文件名首字母必须大写.
      #注: Dockerfile中的每条指令都是一层,层数越多挂载效率越差!!
      #Description: test image
      FROM busybox:latest
      MAINTAINER "Tom <[email protected]>"
      # LABEL maintainer="Tom <[email protected]>"   #功能和上面一样.
      COPY index.html /data/web/html/        #需要将index.html放到/dockerfile中
      COPY yum.repos.d /etc/yum.repos.d/      #注: 先将yum.repos.d 复制党/dcokerfile中, 然后在写此命令.
            
      ADD http://nginx.org/download/nginx-1.15.2.tar.gz /usr/local/src/    #它会自动在打包时下载该URL指定的文件.
      ADD nginx-1.15.2.tar.gz /usr/local/src      #打包时,会自动将tar.gz展开放入/usr/local/src/的文件.

      WORKDIR /usr/local/src    #将它做为工作目录.
      ADD test.tar.gz ./       #这里引用的相对路径就是WORRDIR所设定的目录.

      WORKDIR /etc/yum.repos.d/
      ADD yum.repos.d.tar.gz ./      #这里的相对路径就是/etc/yum.repos.d/了。

      #VOLUME ["/dir_1", "/dir_2" ..]    #设置容器挂载主机目录
      VOLUME /data/mysql/        #指定Docker自动管理的卷。

      #EXPOSE <Port>/<Protocol>
      EXPOSE 80/tcp     
        #指定要对外暴露TCP的80端口,但这里指定暴露,实际并不会直接暴露,而是需要在启动容器时,使用 “-P” 才会真正暴露此端口给外部用户.
           # docker port 容器名 #在不加"-P"时,可使用它来验证是否暴露了80端口.
      #ENV <KeyName> <Value>        #此格式定义的变量,会将空格后面的所有字符串都当做keyname的值.
      #ENV <Key>=<Value> <Key2>=<V2> ...    #此格式可创建多个环节变量. 若值中有空格,需要用"\"转义, 或用引号引起来.
      ENV DOC_ROOT /data/web/html
      COPY *.html $DOC_ROOT
      COPY *.jsp ${JSP_ROOT:-/data/web/jsp/}  #注:这些环境变量,是可以在启动容器时,指定"-e JSP_ROOT=/data/jsp" 来修改的.


      #RUN <Command1> && <Command2> ...      #RUN执行命令是在docker build时执行命令.
      WORKDIR /usr/local/src
      ADD http://test.org/test.tar.gz ./
      RUN cd ./ && \
      tar xf test.tar.gz     #仅做多行写命令的测试

     #RUN ["<Executable>","<Param1>",....]
     #RUN的第二种语法格式.它使用JSON数组,Executable为要运行的命令,后面为命令的参数,可有多个.此格式启动的命令不会以/bin/sh -c 的方式启动,因此它不能使用sh的命令语法,如:变量替换,通配符等. 若想使用shell特性的话,可用以下方式:
    RUN ["/bin/sh","-c","<Executable>","Param1",...]
    注:
      RUN 和 CMD 及 ENTRYPOINT 若使用中括号来表示数组时,其中不能使用单引号.必须使用双引号.


    docker build --tag tinyhttpd:v0.1 ./

  测试:
    docker run --name tinyweb1 --rm tinyhttpd:v0.1 cat /data/web/html/index.html
    docker run --name tinyweb1 --rm tinyhttpd:v0.1 ls /etc/yum.repos.d/

  #启动镜像时,传递参数:
    Dockerfile:
    FROM java:8
    ADD microsoft.jar /root
    ENV PARAMS=""
    ENTRYPOINT ["sh","-c","java $PARAMS -jar /root/microsoft.jar"]

    测试:
      docker run -d -e PARAMS="-Dserver.port=8080" -p 2000:8080 镜像名称


Docker私有仓库的构建:
  1. 安装docker的仓库构建程序包.
    yum install docker-distribution
  2. vim /etc/docker-distribution/registry/config.yml
    services: registry #表示运行的服务为registry
    layerinfo: inmemory #表示缓存在内存中.
    addr: :5000 #没有指定地址,表示使用0.0.0.0:5000

  3.启动服务:
    systemctl start docker-distribution

  4. 给自己做的镜像打上自己的仓库地址的标签.
    docker tag myweb:v0.3.11 node2.test.com:5000/myweb:v0.3.11

  5. 将自己打好标签的镜像push上去.
    docker push node2.test.com:5000/myweb:v0.3.11    #这里会报错,说我们使用了不安全的http.

  6. 若我们是内网使用, 不想使用HTTPS,可修改配置文件为:
    vim /etc/docker/daemon.conf
      {
      ...
      "insecure-registries": ["node2.test.com:5000"]
      }

    systemctl restart docker

  7. 再次push

  8. 可到其它节点上测试下载.
    docker pull node2.test.com:5000/myweb:v0.3.11


Docker的资源限制:
  Linux Capabilities: Linux Kernel相关的知识

  Memory:
  OOM: 对于比较重要的容器,在启动时就要调整其OOM_adj, 其值调整越小, OOM_score的评分就越低,当内核发现内存不足,发生OOM时,就优先将OOM_score得分高的优先kill掉.
  默认: docker daemon会自动将自己的OOM_adj调整很低,避免内核发生OOM时,被内核kill掉.

可调整容器使用内存的限制:
  -m | --memory=    #限制容器能使用的物理内存大小.单位:k, m, g; 若设置一个容器可用内存为4m,若容器使用超过,将被kill掉.
  --memory-swap=    #要使用它,必须先使用 -m 选项,否则它不生效.
    若设置: -m 7G --memory-swap=10G, 则表示Swap+Ram=10G, Swap=10-7=3G,即可使用3G的Swap内存.
    若设置: -m 7G --memory-swap=7G, 则表示不使用Swap内存.即 若设置这两个参数值相同,表示禁用SWAP.
    若设置: -m 7G --memory-swap=0, 则表示SWAP未设置, 则若DockerHost启用了SWAP,则表示容器可用的SWAP大小=2*RAM的大小.
    若设置: -m 7G --memory-swap=-1, 则表示DockerHost上启用了Swap,则容器可使用的全部的SWAP大小.
   注:
    free : 在容器中使用free看到的swap空间使用情况并非上面这些参数计算出来的实际情况, 也就是说free查看容器使用的内存空间是非常不准确的。
    --memory-swappiness: 设置容器使用SWAP内存的倾向性. 值的范围: 0~100, 0:能不用就不用, 100:只要能需要就使用.
    --memory-reservation: 设置要预留多少内存空间。
    --oom-kill-disable 设置当发生OOM时,是否禁止此容器被kill掉,它要可-m一起使用.

CPU:
  默认所有容器使用CPU资源都没有限制。
  --cpu-shares  #CPU是可压缩性资源,若当前有A,B,C三个容器, 假如分配给他们CPU占用的比例为:1024:512:2048.
        则表示,将CPU资源分2+1+4,即分成7份, 三个容器都需要CPU,则A使用2份CPU时间, B使用1份
        CPU时间, C使用4份CPU时间, 若B和C当前都空闲,则A可使用全部CPU资源; 若此时A和B都需要
        用CPU资源,则按照A使用2份CPU资源, B使用1份CPU时间, 若又新加了D,则再重新分割CPU时间片.
  --cpus=   #限制单个容器最多可使用几核CPU, 即: 假如有4个核心, 还是A,B,C, 若此时B和C都不使用CPU
        在不限制的情况下,A可使用4个核心,即最大可使用400%的计算能力.若设置了单个容器的
        最多可使用CPU核心数,则基本当前所有容器都不用CPU,你也只能使用限制个数的核心数.
  --cpus=1.5 #表示最多可用150%,注意容器最多可使用150%的CPU计算能力,指的是
        只有能限制它最多使用这么多计算能力即可,至于容器在那个CPU核心上
        运行无所谓,随机分配,分到那个核心上就在那个核心上运行。但总量是不会超过150%的。
  --cpuset-cpus=     #这是限制容器能够运行在那个CPU核心上的, 假如:有4核心, 则用0~3来表示4个核心的编号.
  --cpuset-cpus=0,1   # 则表示容器只能运行在核心0和1上,其它上面不行。
  --cpu-period=        #限制最多可用CPU的时间.
  --cpu-quota=


以上这些选项在docker run 时可以设置。

docker压测工具:
  docker pull lorel/docker-stress-ng
  docker run --name stress -it --rm -m 256m lorel/docker-stress-ng:latest stress --help #可查看帮助.
  docker run --name stress -it --rm -m 256m lorel/docker-stress-ng:latest stress --vm 2 #限制其最多使用256M内存.
  docker run --name stress -it --rm --cpus 2 lorel/docker-stress-ng:latest stress --cpu 8 #限制最多使用2个CPU核心的计算资源.

  终端1:
    docker run --name stress -it --rm --cpu-shares 1024 lorel/docker-stress-ng:latest stress --cpu 8

  终端3:
    docker run --name stress -it --rm --cpu-shares 512 lorel/docker-stress-ng:latest stress --cpu 8


  终端2:
    docker top stress #查看容器进程数
    docker stats #查看docker资源的消耗情况。

Guess you like

Origin www.cnblogs.com/wn1m/p/11284560.html