zoukankan      html  css  js  c++  java
  • docker基础

    安装

    https://docs.docker.com/install/
    https://docs.docker.com/install/linux/docker-ce/centos/
    

    二进制方式安装

    https://docs.docker.com/install/linux/docker-ce/binaries/
    

    mac安装

    https://docs.docker.com/docker-for-mac/install/
    

    windows10 安装

    https://docs.docker.com/docker-for-windows/install/
    

    镜像

    什么是image
    什么是layer
    搜索下载镜像
    镜像打标签,使用标签

    什么是image

    image = files + metadata

    files文件是构建容器的根文件系统
    metadata包含一些元数据信息

    • 镜像维护者
    • 启动时执行的command
    • 设置环境变量

    images由一层层的files相互堆叠起来, 每一层都可以添加/修改/文件;元数据信息, 镜像层级共享可以节省空间,内存,网络传输消耗等.

    镜像容器概念

    例子: 一个java webapp镜像各个镜像层信息

    • CentOS base layer
    • 基础包与配置依赖
    • JRE
    • Tomcat
    • java webapp 运行时jar依赖
    • java webapp 代码
    • java webapp 配置

    容器镜像区别

    镜像容器对比

    镜像是一个只读的文件
    容器是在该文件系统的读写副本中运行的一组封装的进程。
    为了优化容器启动时间,使用写时拷贝而不是常规拷贝。
    docker run从给定的image启动容器。

    镜像容器与面向对象中概念

    • image概念上类似类(一些成员属性数据)
    • layer概念上类似类的继承
    • 容器类似实例

    镜像基本操作

    修改镜像

    镜像是只读的,如果我们需要对镜像进行修改以适应自己需求,我们无法修改原有镜像!但是我们可以基于此镜像进行修改生成新的镜像,而新的镜像是通过旧的镜像基础修改而来

    创建镜像首先得有一个容器, 而创建一个容器必须得先有镜像,死循环!

    解决方法

    创建一个基础的镜像,生成新的的镜像后,再封装成我们所需要的镜像

    https://docs.docker.com/samples/library/scratch/
    https://docs.docker.com/develop/develop-images/baseimages/
    

    也可以使用 docker import命令导入tarball压缩的docker镜像

    镜像生成

    生成新的镜像有两种方法
    docker commit基于现存容器生成一个新的镜像(很少使用此方法)

    $ docker commit  aae5ef258c76  zrd/flanneld:v1
    sha256:f46a5c369b4f938a5e2b9498813227f5174b54d6601f76d3a2da1eec6367e4f3
    

    docker build(99%情况下使用此方法)

    Images namespaces命名空间

    我们拉取镜像时有以下几种方式

    • 1.默认拉取官方封装好的镜像(官方: 启动docker所设置的docker RegistryURl)
      docker pull centos
    • 2.拉取指定用户构建的镜像
      docker pull zhourudong/myweb
    • 3.完整的地址
      docker pull registry.example.com:5000/my-private/image

    root namespaces一般由官方创建维护比如我们所用的镜像CentOS, mysql
    User namespace一般由用户基于root namespaces自创的镜像例如cucy/busybox,其中cucy是用户名,busybox为镜像
    Self-hosted namespace此命名空间保存的图像不在Docker Hub上,而是在第三方自定义, 例如

    quay.io/coreos/etcd
    gcr.io/google-containers/hugo
    localhost:5000/wordpress
    

    quay.io, gcr.io, localhost:5000是仓库的地址,etcd,hugo,wordpress是镜像

    镜像保存管理

    保存镜像的方法:

    本机
    Remote Docker registry
    

    我们可以使用docker client下载(pull),上传(push)镜像,严格来说是docker client给docker engine发送pull, post请求,由docker

    显示本地所有镜像

    # docker  images
    REPOSITORY                                               TAG                 IMAGE ID            CREATED             SIZE
    zrd/flanneld                                             v1                  f46a5c369b4f        About an hour ago   52.6MB
    findsec/hello                                            v2                  72f0edcf0c06        4 days ago          941MB
    findsec/hello                                            v1                  c54843059b2b        4 days ago          941MB
    calico/node                                              v3.8.0              cd3efa20ff37        10 days ago         155MB
    calico/cni                                               v3.8.0              539ca36a4c13        10 days ago         143MB
    calico/kube-controllers                                  v3.8.0              df5ff96cd966        10 days ago         46.8MB
    calico/pod2daemon-flexvol                                v3.8.0              f68c8f870a03        13 days ago         9.37MB
    gcr.azk8s.cn/google-containers/kube-proxy                v1.15.0             d235b23c3570        3 weeks ago         82.4MB
    

    搜索镜像

    # docker search busybox
    NAME                      DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
    busybox                   Busybox base image.                             1623                [OK]                
    progrium/busybox                                                          70                                      [OK]
    radial/busyboxplus        Full-chain, Internet enabled, busybox made f…   24                                      [OK]
    arm32v7/busybox           Busybox base image.                             7                                       
    yauritux/busybox-curl     Busybox with CURL                               5                                       
    armhf/busybox             Busybox base image.                             4                                       
    arm64v8/busybox           Busybox base image.                             3                                       
    

    OFFICIAL 表示是官方镜像
    AUTOMATED自动构建

    下载镜像

    docker pull指定下载镜像
    docker run当本地没有此镜像时,会到docker仓库进行拉取

    tag打标签

    docker tag busybox:latest zrd:prod-v1

    适合使用标签场景

    快速测试使用
    正在开发环境调式
    使用latest版本
    

    适合打标签场景

    在脚本中定义版本信息
    生产环境
    重复使用
    

    练习

    从基础镜像运行一个容器

    安装一些基础软件,然后生成新的镜像

    使用docker commit, docker tag, and docker diff 等命令

    主机上执行
    # docker run -it centos
    
    容器内运行
    [root@1e42384795b3 /]# yum install wget -y && rm -rf /var/cache/yum
    
    
    
    容器所修改的内容
    [root@k8s-master-45 ~]# docker diff  fb62137afd63
    C /usr
    C /usr/bin
    A /usr/bin/wget
    C /usr/share
    C /usr/share/locale
    C /usr/share/locale/en_GB
    C /usr/share/locale/en_GB/LC_MESSAGES
    A /usr/share/locale/en_GB/LC_MESSAGES/wget.mo
    
    
    主机上执行 $ docker commit <yourContainerId>
    
    # docker commit fb62137afd63  zrd/centostest
    
    
    

    **镜像是只读,当我们对其进行修改时,它会拷贝修改的文件到新的镜像, **, 基于性能出发点,docker使用copy-on-write技术

    验证生成的镜像

    # docker run zrd/centostest wget baidu.com 
    --2019-07-12 09:44:48--  http://baidu.com/
    Resolving baidu.com (baidu.com)... 123.125.114.144, 220.181.38.148
    Connecting to baidu.com (baidu.com)|123.125.114.144|:80... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 81 [text/html]
    Saving to: 'index.html'
    
         0K                                                       100% 12.9M=0s
    
    2019-07-12 09:44:48 (12.9 MB/s) - 'index.html' saved [81/81]
    

    打标签

    两种打标签方法

    $ docker tag <newImageId> figlet
    $ docker commit <containerId> figlet
    

    以上构建镜像方法过于繁杂, Dockerfile应运而生

    使用Dockerfile来构建镜像

    从Doclerfile构建镜像

    $ vim Dockerfile

    FROM ubuntu
    RUN apt-get update
    RUN apt-get install figlet
    

    FROM 指定从哪个基础镜像开始构建
    RUN 每一个RUN指令就是构建一个镜像, RUN 运行的命令不能有交互

    $ docker build -t figlet .
    

    -t 表示指定标签
    . 表示以当前目录下Dockerfile中所定义的步骤进行构建镜像

    构建时,显示的内容

    [root@k8s-master-45 ~/myimage]# docker build -t figlet .
    Sending build context to Docker daemon  2.048kB
    Step 1/3 : FROM ubuntu
     ---> 4c108a37151f
    Step 2/3 : RUN apt-get update
     ---> Running in 6c0d73559f78
    Removing intermediate container 5e624609a7f1
     ---> 81def0f272fc
    Successfully built 81def0f272fc
    Successfully tagged figlet:latest
    

    context Sending build context to Docker daemon 2.048kB

    因为docker client 和Docker daemon(Engine)可以在不同的主机上,在构建时,docker client 需要将本地数据上传给docker daemo(压缩); 在构建时如果docker client 和docker engine不在同一台主机上时,上传本地文件数据会耗费很长的时间

    docker build --no-cache

    docker history figlet

    CMD and ENTRYPOINT

    CMD / ENTRYPOINT 这两个命令可以设置容器启动时容器运行的命令参数

    CMD

    FROM ubuntu
    RUN apt-get update
    RUN ["apt-get", "install", "figlet"]
    CMD figlet -f script hello
    

    不加指定参数默认以CMD定义的命令来运行

    [root@k8s-master-45 ~/myimage]# docker run figlet
     _          _   _
    | |        | | | |
    | |     _  | | | |  __  
    |/    |/  |/  |/  /  \_
    |   |_/|__/|__/|__/\__/
    

    覆盖CMD 默认设定的命令

    $ docker run -it figlet bash
    root@7ac86a641116:/#
    

    ENTRYPOINT

    FROM ubuntu
    RUN apt-get update
    RUN ["apt-get", "install", "figlet"]
    ENTRYPOINT ["figlet", "-f", "script"]
    

    运行测试

    $ docker run figlet salut
               _            
              | |           
     ,   __,  | |       _|_ 
    / \_/  |  |/  |   |  |  
     / \_/|_/|__/ \_/|_/|_/
    

    使用 CMD 还是 ENTRYPOINT?

    两个可以同时并存, ENTRYPOINT 作为基本执行命令不会被覆盖,如果使用CMD命令会被全部覆盖;所以ENTRYPOINT作为容器的基本命令,而CMD定义为默认的参数

    FROM ubuntu
    RUN apt-get update
    RUN ["apt-get", "install", "figlet"]
    ENTRYPOINT ["figlet", "-f", "script"]
    CMD ["hello world"]
    

    以上例子,当容器运行后,如果不给参数则命令 CMD是默认的参数; 如果启动时给定参数,CMD 设置的参数会被覆盖.

    # docker build -t figlet .
    Sending build context to Docker daemon  2.048kB
    Step 1/5 : FROM ubuntu
    ....
    
    
    以默认参数运行
    # docker run figlet
     _          _   _                             _        
    | |        | | | |                           | |    |  
    | |     _  | | | |  __             __   ,_   | |  __|  
    |/    |/  |/  |/  /  \_  |  |  |_/  \_/  |  |/  /  |  
    |   |_/|__/|__/|__/\__/    / /  \__/    |_/|__/\_/|_/
    
    覆盖默认参数
    # docker run figlet 123
     , __  ___ 
    /|/  )/   
     |  /   __/
     | /      
     |/___\___/		                                               
    

    强制覆盖ENTRYPOINT

    我们可以使用--entrypoint覆盖基本命令

    $ docker run -it --entrypoint bash figlet
    root@6027e44e2955:/#
    

    CPOY /ADD

    时候构建代码时,代码并不在容器中(在宿主机上), 我们需要使用COPY 或者ADD命令将本地文件拷贝到容器中

    代码内容如下

    # cat  hellogo.go
    
    package main
    
    func main() {
    	println("Hi, golang!")
    }
    

    Dockerfile

    FROM ubuntu
    RUN apt-get update
    RUN apt-get install -y golang
    COPY  hellogo.go /
    RUN GOPATH=/ && go build -o hellogo .
    CMD /hellogo
    

    CPOY /ADD类似, ADD可以解压压缩文件(展开压缩文件的内容,而不是把整个压缩包往容器里添加)

    减少镜像大小

    以最小依赖来安装软件包, 构建完成前可以清理一些缓存,比如apt yum 的cache目录

    docker image build --squash ... 压缩成单一层镜像

    Multi-stage builds 多阶段构建

    FROM ubuntu AS compiler
    RUN apt-get update
    RUN apt-get install -y golang
    COPY  hellogo.go /
    RUN GOPATH=/ && go build -o hellogo .
    
    FROM ubuntu 
    COPY  --from=compiler hellogo.go /
    CMD /hellogo
    

    镜像仓库管理

    docker  login 
    
    # 登录信息会保存在 ~/.docker/config
    
    
    docker target image someimage zrd/someimage
    
    docker push zrd/someimage
    

    Dockerfile tip

    entrypoint script

    #!/bin/sh
     set -e
     # first arg is '-f' or '--some-option'
     # or first arg is 'something.conf'
     if [ "${1#-}" != "$1" ] || [ "${1%.conf}" != "$1" ]; then
         set -- redis-server "$@"
     fi
     # allow the container to be started with '--user'
     if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then
         chown -R redis .
         exec su-exec redis "$0" "$@"
     fi
     exec "$@"
    
    $ docker inspect --format '{{ json .Created }}' <containerID>
    "2015-02-24T07:21:11.712240394Z"
    
    

    docker label

    docker run -d -l owner=alice nginx
    docker run -d -l owner=bob nginx
    docker run -d -l owner nginx
    
    
    
    $ docker inspect $(docker ps -lq) | grep -A3 Labels
                "Labels": {
                    "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>",
                    "owner": ""
                },
    
    $ docker inspect $(docker ps -q) --format 'OWNER={{.Config.Labels.owner}}'
    
    
    
    $ docker ps --filter label=owner
    Or we can list containers having a specific label with a specific value.
    
    $ docker ps --filter label=owner=alice
    
    
    docker cp <container_id>:/var/log/nginx/error.log .
    docker run -ti --entrypoint sh debugimage
    
    

    资源限制

    内存

    docker run -ti --memory 100m python
    

    cpu

    --cpus 0.1 means 10% of one CPU,
    
    --cpus 1.0 means 100% of one whole CPU,
    
    --cpus 10.0 means 10 entire CPUs.
    
    
    --cpuset-cpus 0 forces the container to run on CPU 0;
    
    --cpuset-cpus 3,5,7 restricts the container to CPUs 3, 5, 7;
    
    --cpuset-cpus 0-3,8-11 restricts the container to CPUs 0, 1, 2, 3, 8, 9, 10, 11.
    

    docker 网路

    docker run --net none ...
    
    
    

    单网络容器

    !()[bridge1.png]

    Two containers on a single Docker network

    !()[bridge2.png]

    Two containers on two Docker networks

    !()[bridge3.png]

    创建网络

    docker network create dev
    
    $ docker run -d --name es --net dev elasticsearch:2
    
    $ docker run -ti --net dev alpine sh
    
    $ docker run --net dev --net-alias redis -d redis
    
    
    
    --internal  
    
    --gateway 
    
    --subnet  
    
    --ip-range  
    
    --aux-address 
    
    
    
    $ docker network create --subnet 10.66.0.0/16 pubnet
    
    $ docker run --net pubnet --ip 10.66.66.66 -d nginx
    
    
    docker network connect <network> <container>
    
    docker network disconnect <network> <container>
    
    docker network connect dev <container_id>
    
  • 相关阅读:
    NYOJ 542 试制品(第五届河南省省赛)
    714-Card Trick
    716-River Crossing
    1248-海岛争霸
    51Nod
    51Nod
    NYOJ_1274_信道安全
    ZZNU 2095 : 我只看看不写题
    前端-HTML标签
    python 17篇 unittest单元测试框架
  • 原文地址:https://www.cnblogs.com/zrdpy/p/11176687.html
Copyright © 2011-2022 走看看