C语言 c++ php mysql nginx linux lnmp lamp lanmp memcache redis 面试 笔记 ppt 设计模式 问题 远程连接

随笔 - 301  文章 - 1  评论 - 49 

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

   镜像:

    轻量级,可独立执行的软件包,用来打包软件运行环境基于运行环境开发的软件,包括代码、运行库、环境变量、配置文件。

    镜像都是只读的

   scratch镜像

该镜像是一个空的镜像没有任何内容,只能执行静态编译的命令,可以用于构建 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运行在一个轻量级的虚拟机中

    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  的私服

  

 手写 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 

  看到输出则表示成功

 

参考:

  操作系统层虚拟化

      Hypervisor(硬件虚拟化)

  LXC,其名称来自Linux软件容器(Linux Containers)

    清华大学开源软件镜像站

  Add libraries for static compilation CentOS 8

  Inside Docker's "FROM scratch"

  HyperKit

    Mac Hypervisor.framework

  Docker for Mac 的网络问题及解决办法 

 
posted on 2020-07-06 00:04  思齐_  阅读(72)  评论(0编辑  收藏