docker

一、详解docker镜像,容器,仓库

官网说明:https://docs.docker.com/get-started/overview/

docker架构

docker镜像

镜像可以理解为创建实例使用的模板。

镜像是一个只读模板,其中包含创建 Docker 容器的说明 通常,一个镜像基于另一个镜像,并带有一些额外的自定义。例如,可以基于镜像ubuntu 构造一个镜像,可以安装 Apache Web 服务和应用程序,以及配置应用程序运行所需的详细信息。

docker的镜像是分层的,镜像底层为库文件且为只读层即不能写入也不能删除数据,从镜像加载启动为一个容器后会生成一个可写层,其写入的数据会复制到容器目录,但是容器内的数据在删除容器后也会随之删除。

docker容器

容器是从镜像生成对外提供服务的一个或一组服务。

容器是镜像的可运行实例。可以使用 Docker API 或 CLI 创建、启动、停止、移动或删除容器。可以将容器连接到一个或多个网络,将存储附加到它,甚至可以根据其当前状态创建新镜像。
默认情况下,一个容器与其他容器及其主机的隔离相对较好。可以控制容器的网络、存储或其他底层子系统与其他容器或主机的隔离程度。
容器由其镜像以及在创建或启动它时提供给它的任何配置选项定义。当容器被移除时,任何未存储在持久存储中的状态更改都会消失。

示例docker run命令

以下命令运行一个ubuntu容器,以交互方式附加到本地命令行会话,然后运行/bin/bash.

$ docker run -i -t ubuntu /bin/bash

当运行此命令时,会发生以下情况(假设使用的是默认镜像仓库配置):

  1. 如果本地没有ubuntu镜像,Docker 会从配置的镜像仓库中提取它,就像docker pull ubuntu手动运行一样。
  2. Docker 会创建一个新容器,就像docker container create 手动运行命令一样。
  3. Docker 为容器分配一个读写文件系统,作为它的最后一层。这允许正在运行的容器在其本地文件系统中创建或修改文件和目录。
  4. Docker 创建了一个网络接口来将容器连接到默认网络,因为没有指定任何网络选项。这包括为容器分配 IP 地址。默认情况下,容器可以使用主机的网络连接连接到外部网络。
  5. Docker 启动容器并执行/bin/bash。因为容器以交互方式运行并附加到你的终端(-i-t 选项),你可以在输出记录到终端时使用键盘提供输入。
  6. 当输入exit停止/bin/bash命令时,容器会停止但不会被删除。你可以重新启动或删除它。

docke仓库

统一保存镜像而且是多个镜像版本的地方,叫做镜像仓库。

Image registry:docker 官方提供的使用仓库部署工具。

Docker hub: docker 官方的公共仓库,已经保存了大量的常见镜像,可以方便大家直接使用。

Harbor:vmware提供的自带Web界面、认证功能的镜像仓库。

当使用docker pulldocker run命令时,将从你配置的仓库中提取所需的镜像。当使用docker push命令时,镜像会被推送到配置的仓库中。

二、docker安装及基础命令使用

ubuntu20安装docker

apt安装

  1. 设置仓库

    • 安装依赖包
    apt update
    apt install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
    • 添加docker官方GPG key
    mkdir -p /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    • 设置仓库
    echo \
    "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    或者设置清华镜像源
    echo \
    "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu \
    $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  2. 安装Docker Engine

    apt update
    apt -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin

一键安装

#! /bin/bash
apt update
apt install \
ca-certificates \
curl \
gnupg \
lsb-release
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sed -i '/GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"/c GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 cgroup_enable=memory swapaccount=1"' /etc/default/grub
update-grub
reboot

二进制安装

deb包官网下载地址:https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/

找到对应的containerd.io docker-ce docker-ce-cli版本

  1. 下载deb包

    cd /opt
    wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/containerd.io_1.4.13-1_amd64.deb
    wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/docker-ce_20.10.0_3-0_ubuntu-focal_amd64.deb
    wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/docker-ce-cli_20.10.0_3-0_ubuntu-focal_amd64.deb
  2. 安装deb包

    dpkg -i containerd.io_1.4.3-1_amd64.deb \
    docker-ce_20.10.0_3-0_ubuntu-focal_amd64.deb \
    docker-ce-cli_20.10.0_3-0_ubuntu-focal_amd64.deb

安装后验证

  1. 验证docker服务启动

    [root@master ~]#systemctl status docker
    ● docker.service - Docker Application Container Engine
    Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
    Active: active (running) since Thu 2022-08-11 20:38:12 CST; 7min ago
    TriggeredBy: ● docker.socket
    Docs: https://docs.docker.com
    Main PID: 1144 (dockerd)
    Tasks: 10
    Memory: 134.6M
    CGroup: /system.slice/docker.service
    └─1144 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
    Aug 11 20:38:12 master dockerd[1144]: time="2022-08-11T20:38:12.095036794+08:00" level=warning msg="Your kernel does not support CPU realtime schedul>
    Aug 11 20:38:12 master dockerd[1144]: time="2022-08-11T20:38:12.095282943+08:00" level=warning msg="Your kernel does not support cgroup blkio weight"
    Aug 11 20:38:12 master dockerd[1144]: time="2022-08-11T20:38:12.095430841+08:00" level=warning msg="Your kernel does not support cgroup blkio weight_>
    Aug 11 20:38:12 master dockerd[1144]: time="2022-08-11T20:38:12.095878025+08:00" level=info msg="Loading containers: start."
    Aug 11 20:38:12 master dockerd[1144]: time="2022-08-11T20:38:12.360911478+08:00" level=info msg="Default bridge (docker0) is assigned with an IP addr>
    Aug 11 20:38:12 master dockerd[1144]: time="2022-08-11T20:38:12.414411346+08:00" level=info msg="Loading containers: done."
    Aug 11 20:38:12 master dockerd[1144]: time="2022-08-11T20:38:12.480842035+08:00" level=info msg="Docker daemon" commit=eeddea2 graphdriver(s)=overlay>
    Aug 11 20:38:12 master dockerd[1144]: time="2022-08-11T20:38:12.481256266+08:00" level=info msg="Daemon has completed initialization"
    Aug 11 20:38:12 master systemd[1]: Started Docker Application Container Engine.
    Aug 11 20:38:12 master dockerd[1144]: time="2022-08-11T20:38:12.523898401+08:00" level=info msg="API listen on /run/docker.sock"
  2. 验证docker版本

    Client: Docker Engine - Community
    Version: 20.10.17
    API version: 1.41
    Go version: go1.17.11
    Git commit: 100c701
    Built: Mon Jun 6 23:02:57 2022
    OS/Arch: linux/amd64
    Context: default
    Experimental: true
    Server: Docker Engine - Community
    Engine:
    Version: 20.10.17
    API version: 1.41 (minimum version 1.12)
    Go version: go1.17.11
    Git commit: a89b842
    Built: Mon Jun 6 23:01:03 2022
    OS/Arch: linux/amd64
    Experimental: false
    containerd:
    Version: 1.6.7
    GitCommit: 0197261a30bf81f1ee8e6a4dd2dea0ef95d67ccb
    runc:
    Version: 1.1.3
    GitCommit: v1.1.3-0-g6724737
    docker-init:
    Version: 0.19.0
    GitCommit: de40ad0
  3. 验证docker0网卡

    在docker安装启动后,默认会生成一个docker0的网卡并且默认IP地址为172.17.0.1。

    [root@master ~]#ifconfig
    docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
    inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
    ether 02:42:a9:7a:ba:0b txqueuelen 0 (Ethernet)
    RX packets 0 bytes 0 (0.0 B)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 0 bytes 0 (0.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
    inet 10.0.0.12 netmask 255.255.255.0 broadcast 10.0.0.255
    inet6 fe80::20c:29ff:fe2b:7e79 prefixlen 64 scopeid 0x20<link>
    ether 00:0c:29:2b:7e:79 txqueuelen 1000 (Ethernet)
    RX packets 380 bytes 58835 (58.8 KB)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 363 bytes 50907 (50.9 KB)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
  4. 验证docker信息

    Client:
    Context: default
    Debug Mode: false
    Plugins:
    app: Docker App (Docker Inc., v0.9.1-beta3)
    buildx: Docker Buildx (Docker Inc., v0.8.2-docker)
    compose: Docker Compose (Docker Inc., v2.6.0)
    scan: Docker Scan (Docker Inc., v0.17.0)
    Server:
    Containers: 1 #当前主机运行的容器总数
    Running: 0 #正在运行的容器数
    Paused: 0 #暂停的容器数
    Stopped: 1 #停止的容器数
    Images: 1 #当前服务器的镜像数
    Server Version: 20.10.17 #服务端版本
    Storage Driver: overlay2 #存储引擎
    Backing Filesystem: xfs #服务器的磁盘文件系统
    Supports d_type: true #是否支持d_type
    Native Overlay Diff: true #是否支持差异数据存储
    userxattr: false
    Logging Driver: json-file #日志类型
    Cgroup Driver: cgroupfs #Cgroup类型
    Cgroup Version: 1 #Cgroup版本
    Plugins: #插件
    Volume: local #本地卷
    Network: bridge host ipvlan macvlan null overlay #overlay跨主机通信
    Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog #日志类型
    Swarm: inactive #是否支持swarm
    Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc #已安装的容器运行时
    Default Runtime: runc #默认使用的容器运行时
    Init Binary: docker-init #初始化容器的守护进程,即pid为1的进程
    containerd version: 0197261a30bf81f1ee8e6a4dd2dea0ef95d67ccb #容器版本
    runc version: v1.1.3-0-g6724737 #runc版本
    init version: de40ad0 #初始化版本
    Security Options: #安全选项
    apparmor #安全模块
    seccomp #审计操作
    Profile: default #默认的配置文件
    Kernel Version: 5.4.0-122-generic #宿主机内核版本
    Operating System: Ubuntu 20.04.4 LTS #宿主机操作系统
    OSType: linux #宿主机操作系统类型
    Architecture: x86_64 #宿主机系统架构
    CPUs: 2 #宿主机CPU数量
    Total Memory: 1.907GiB #宿主机总内存
    Name: master #宿主机主机名
    ID: M74L:JXAO:477C:EEU5:3IEZ:4ETF:SWD7:TBTH:NFVD:TUHL:BAVQ:LGYV #宿主机ID
    Docker Root Dir: /var/lib/docker #宿主机数据保存目录
    Debug Mode: false #是否开启debug
    Registry: https://index.docker.io/v1/ #镜像仓库
    Labels: #标签
    Experimental: false #是否测试版本
    Insecure Registries: #非安全的镜像仓库
    127.0.0.0/8
    Live Restore Enabled: false #是否开启活动重启(重启docker-daemon不关闭容器)
    WARNING: No swap limit suppprt #系统警告信息(没有开启swap资源限制)
  5. 解决swap限制告警

    [root@master ~]#vim /etc/default/grub
    # 对该行进行修改
    GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 cgroup_enable=memory swapaccount=1"

    修改完成后执行命令:update-grub

    重启服务器:reboot

  6. 下载镜像并运行,验证docker安装正确

    • 下载hello-world镜像
    docker pull hello-world
    • 运行hello-world镜像
    [root@master ~]#docker run hello-world
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    To generate this message, Docker took the following steps:
    1. The Docker client contacted the Docker daemon.
    2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
    3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
    4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.
    To try something more ambitious, you can run an Ubuntu container with:
    $ docker run -it ubuntu bash
    Share images, automate workflows, and more with a free Docker ID:
    https://hub.docker.com/
    For more examples and ideas, visit:
    https://docs.docker.com/get-started/

docker基础命令使用说明

镜像相关操作命令

docker search nginx #搜索nginx镜像
docker pull nginx #下载nginx镜像
docker push nginx #上传nginx镜像
docker images #查看本地镜像
docker save nginx > /opt/nginx.tar.gz #导出nginx镜像
docker load nginx < /opt/nginx.tar.gz #导入nginx镜像
docker rmi nginx/nginxID #删除指定nginx或nginx ID镜像
docker rm 容器ID/容器名称 #删除容器
docker rm -f 容器ID/容器名称 #强制删除正在运行的容器

容器相关操作命令

命令格式:

docker run[选项][镜像名][shell命令][参数]
docker run[参数选项][镜像名称,必须在所有选项的后面][/bin/echo 'hellowold'] #单次执行,没有自定义容器名称
docker run centos /bin/echo 'hello world' #启动的容器在执行完shell命令后就退出了
  1. 从镜像启动一个容器

    直接进入到容器,并随机生成容器ID和名称

    docker run -it 镜像 sh

    [root@master ~]#docker run -it alpine sh
    / # ls
    bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var

    退出容器不注销Ctrl + p + q

  2. 显示正在运行的容器

    docker ps

    示例

    [root@master ~]#docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    77e9c0722bbc nginx "/docker-entrypoint.…" 9 seconds ago Up 8 seconds 80/tcp zen_leavitt
  3. 显示所有容器,包括运行以及关闭的容器

    docker ps -a

    示例

    [root@master ~]#docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    77e9c0722bbc nginx "/docker-entrypoint.…" 41 seconds ago Up 40 seconds 80/tcp zen_leavitt
    5c0c3276fcf0 nginx "/docker-entrypoint.…" 4 minutes ago Exited (130) 4 minutes ago blissful_murdock
    c6585a44ccf1 hello-world "/hello" 57 minutes ago Exited (0) 57 minutes ago nostalgic_lewin
  4. 删除运行中的容器

    docker rm -f 容器ID

    示例

    [root@master ~]#docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    c8dc7052aefe nginx "/docker-entrypoint.…" 6 seconds ago Up 5 seconds 80/tcp strange_galileo
    [root@master ~]#docker rm -f c8dc7052aefe
    c8dc7052aefe
    [root@master ~]#docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. 随机映射端口

    docker run -P nginx 前台启动并随机映射本地端口到容器的80端口

    示例

    # 前台启动的会话窗口无法进行其他操作,除非退出,但退出后容器也会退出
    [root@master ~]#docker run -P nginx
    /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
    /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
    10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
    10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
    # 随机端口映射,49153
    [root@master ~]#netstat -ntlp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
    tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 781/systemd-resolve
    tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 860/sshd: /usr/sbin
    tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN 1306/sshd: root@pts
    tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 1306/sshd: root@pts
    tcp 0 0 0.0.0.0:49153 0.0.0.0:* LISTEN 5035/docker-proxy #docker-proxy
    tcp6 0 0 :::22 :::* LISTEN 860/sshd: /usr/sbin
    tcp6 0 0 ::1:6010 :::* LISTEN 1306/sshd: root@pts
    tcp6 0 0 ::1:6011 :::* LISTEN 1306/sshd: root@pts
    tcp6 0 0 :::49153 :::* LISTEN 5042/docker-proxy #docker-proxy

    访问49153随机端口

  6. 指定端口映射

    方式1:本地端口81映射到容器80端口:

    docker run -d -p 81:80 --name nginx-test-port1 nginx

    方式2:本地IP:本地端口:容器端口

    docker run -d -p 10.0.0.12:82:80 --name nginx-test-port2 nginx

    方式3:本地IP:本地随机端口:容器端口

    docker run -d -p 10.0.0.12::80 --name nginx-test-port3 nginx

    方式4:本机 ip:本地端口:容器端口/协议,默认为tcp协议
    docker run -d -p 10.0.0.12:83:80/udp --name nginx-test-port4 nginx
    方式5:一次性映射多个端口+协议:

    docker run -d -p 86:80/tcp -p 443:443/tcp -p 53:53/udp --name nginx-test-port5 nginx

    执行命令

    [root@master ~]#docker run -d -p 81:80 --name nginx-test-port1 nginx
    dce5a20899bd9fbd8d2ad6db0eeb569f30d01561d7f50bf2ed550a4440bb0e6b
    [root@master ~]#docker run -d -p 10.0.0.12:82:80 --name nginx-test-port2 nginx
    b4e656786326135884f6904ad93f2588b176d8b38d80708872182d50c0529a0a
    [root@master ~]#docker run -d -p 10.0.0.12::80 --name nginx-test-port3 nginx
    a4bec451f8d10d4db2062a34ccae99a75badbcc2055305f8a6b7772b596144c4
    [root@master ~]#docker run -d -p 10.0.0.12:83:80/udp --name nginx-test-port4 nginx
    e93bf7ad5f88b65de36f80dea933f22df824c49c1589d21d54e883035e95b67b
    [root@master ~]#docker run -d -p 86:80/tcp -p 443:443/tcp -p 60:53/udp --name nginx-test-port5 nginx
    858a2fb354f9a273fe9d9d3021987eb2f8c67907ad9ed8cb76bbcf5ae0b5d86b

    查看运行容器

    [root@master ~]#docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    858a2fb354f9 nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:443->443/tcp, :::443->443/tcp, 0.0.0.0:60->53/udp,
    :::60->53/udp, 0.0.0.0:86->80/tcp, :::86->80/tcp nginx-test-port5
    e93bf7ad5f88 nginx "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 80/tcp, 10.0.0.12:83->80/udp nginx-test-port4
    a4bec451f8d1 nginx "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 10.0.0.12:49153->80/tcp nginx-test-port3
    b4e656786326 nginx "/docker-entrypoint.…" 4 minutes ago Up 4 minutes 10.0.0.12:82->80/tcp nginx-test-port2
    dce5a20899bd nginx "/docker-entrypoint.…" 4 minutes ago Up 4 minutes 0.0.0.0:81->80/tcp, :::81->80/tcp nginx-test-port1
  7. 查看容器已经映射的端口

    docker port nginx-test-port5

    [root@master ~]#docker port nginx-test-port5
    443/tcp -> 0.0.0.0:443
    443/tcp -> :::443
    53/udp -> 0.0.0.0:60
    53/udp -> :::60
    80/tcp -> 0.0.0.0:86
    80/tcp -> :::86
  8. 自定容器名称

    docker run -it --name nginx-test nginx

    示例:

    生成对应的容器名称为nginx-test

    [root@master ~]#docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    4e356a21eb20 nginx "/docker-entrypoint.…" 7 seconds ago Up 6 seconds 80/tcp nginx-test
  9. 后台启动容器

    示例

    [root@master ~]#docker run -d -P --name nginx-test2 nginx
    df99000a5d819fefee018af9f50625aca5c1cc619d07a9f0b933e99290907943
    [root@master ~]#docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    df99000a5d81 nginx "/docker-entrypoint.…" 2 seconds ago Up 1 second 0.0.0.0:49155->80/tcp, :::49155->80/tcp nginx-test2
    [root@master ~]#
  10. 创建并进入容器

    docker run -it --name alpine alpine sh

    示例

    执行exit退出后容器关闭

    [root@master ~]#docker run -it --name alpine alpine sh
    / # ps aux
    PID USER TIME COMMAND
    1 root 0:00 sh
    6 root 0:00 ps aux
    / # exit
  11. 单次运行

    容器退出后自动删除

    [root@master ~]#docker run -it --rm --name alpine-del alpine sh
    / # ps aux
    PID USER TIME COMMAND
    1 root 0:00 sh
    7 root 0:00 ps aux
    / # exit
    [root@master ~]#docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  12. 传递运行命令

    容器需要有一个前台运行的进程才能保持容器的运行,通过传递运行参数是一种方式,另外也可以在构建镜像的时候指定容器启动时运行的前台命令。

    示例

    [root@master ~]#docker run -d alpine /usr/bin/tail -f '/etc/hosts'
    35a6a61ecdb24ed4602038444101923d420ad2508f85c7ee8bd54a0c5bad69bb
    [root@master ~]#docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    35a6a61ecdb2 alpine "/usr/bin/tail -f /e…" 17 seconds ago Up 16 seconds amazing_saha
  13. 容器的启动和关闭

    示例

    # 容器关闭
    [root@master ~]#docker stop 35a6a61ecdb2
    35a6a61ecdb2
    [root@master ~]#docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    35a6a61ecdb2 alpine "/usr/bin/tail -f /e…" About a minute ago Exited (137) 12 seconds ago amazing_saha
    #容器启动
    [root@master ~]#docker start 35a6a61ecdb2
    35a6a61ecdb2
    [root@master ~]#docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    35a6a61ecdb2 alpine "/usr/bin/tail -f /e…" About a minute ago Up 1 second amazing_saha amazing_saha
  14. 进入到正在运行的容器

    • 使用attach命令

      使用方式为docker attach 容器名,attach类似于vnc,操作会在各个容器界面显示,所有使用此方式进入容器的操作都是同步显示的且exit后容器将被关闭,且使用exit退出后容器关闭,不推荐使用,需要进入到有shell环境的容器。

      [root@master ~]#docker ps
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      50be401c3aae alpine "sh" 2 minutes ago Up 2 minutes agitated_mclaren
      [root@master ~]#docker attach 50be401c3aae
      / # exit
      [root@master ~]#docker ps
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    • 使用exec命令

      执行单次命令与进入容器,不是很推荐此方式,虽然exit退出容器还在运行

      [root@master ~]#docker ps
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      50be401c3aae alpine "sh" 32 seconds ago Up 32 seconds agitated_mclaren
      [root@master ~]#docker exec -it 50be401c3aae sh
      / # ls
      bin etc lib mnt proc run srv tmp var
      dev home media opt root sbin sys usr
      / # exit
      [root@master ~]#docker ps
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      50be401c3aae alpine "sh" About a minute ago Up About a minute agitated_mclaren
    • 使用nsenter

      推荐使用此方式,nsenter命令需要通过PID进入到容器内部,可以使用docker inspect获取到容器的PID

      [root@master ~]#docker ps
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      951d347760c7 nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 80/tcp romantic_keller
      # 获取容器的IP地址
      [root@master ~]#docker inspect -f "{{.NetworkSettings.IPAddress}}" 951d347760c7
      172.17.0.2
      # 获取容器的PID
      [root@master ~]#docker inspect -f "{{.State.Pid}}" 951d347760c7
      12475
      [root@master ~]#nsenter -t 12475 -m -u -i -n -p
      root@951d347760c7:/# ls
      bin docker-entrypoint.d home media proc sbin tmp
      boot docker-entrypoint.sh lib mnt root srv usr
      dev etc lib64 opt run sys var
      root@951d347760c7:/# exit
      logout
      [root@master ~]#docker ps
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      951d347760c7 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp romantic_keller
    • 脚本方式

      将nsenter命令写入脚本进行调用,脚本内容为

      [root@master ~]#cat docker-in.sh
      #!/bin/bash
      docker_in(){
      NAME_ID=$1
      PID=$(docker inspect -f "{{.State.Pid}}" ${NAME_ID})
      nsenter -t ${PID} -m -u -i -n -p
      }
      docker_in $1

      [root@master ~]#chmod a+x docker-in.sh

      调用脚本,可正常进入容器,exit退出后,容器仍然运行

      [root@master ~]#docker ps
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      951d347760c7 nginx "/docker-entrypoint.…" 7 minutes ago Up 7 minutes 80/tcp romantic_keller
      [root@master ~]#./docker-in.sh 951d347760c7
      root@951d347760c7:/# pwd
      /
      root@951d347760c7:/# exit
      logout
      [root@master ~]#docker ps
      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
      951d347760c7 nginx "/docker-entrypoint.…" 7 minutes ago Up 7 minutes 80/tcp romantic_keller
  15. 查看容器内部的hosts文件

    [root@master ~]#docker run -it alpine sh
    / # cat /etc/hosts
    127.0.0.1 localhost
    ::1 localhost ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
    172.17.0.2 a5f544c5365a #默认会将容器实例的ID添加至自己的hosts文件
    / # ping a5f544c5365a #ping 容器ID
    PING a5f544c5365a (172.17.0.2): 56 data bytes
    64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.129 ms
    64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.063 ms
    ^C
    --- a5f544c5365a ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.063/0.096/0.129 ms
    / #
  16. 批量正常关闭正在运行的容器

    示例

    [root@master ~]#docker stop $(docker ps -a -q)
    a5f544c5365a
    6c0af66c3052
  17. 批量强制关闭正在运行的容器

    [root@master ~]#docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    a5f544c5365a alpine "sh" 5 minutes ago Up 9 seconds intelligent_lehmann
    6c0af66c3052 nginx "/docker-entrypoint.…" 6 minutes ago Up 8 seconds 80/tcp wonderful_maxwell
    [root@master ~]#docker kill $(docker ps -a -q)
    a5f544c5365a
    6c0af66c3052
    [root@master ~]#docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  18. 批量删除已退出容器

    docker rm -f $(docker ps -a -q -f status=exited)

    docker ps -a|grep "Exited"|awk '{print $1}'也可获取退出容器ID

    示例

    [root@master ~]#docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    2a2bb4fc9904 nginx "/docker-entrypoint.…" About a minute ago Up About a minute 80/tcp peaceful_noether
    a5f544c5365a alpine "sh" 10 minutes ago Exited (137) 5 minutes ago intelligent_lehmann
    6c0af66c3052 nginx "/docker-entrypoint.…" 11 minutes ago Exited (137) 5 minutes ago wonderful_maxwell
    [root@master ~]#docker rm -f $(docker ps -a -q -f status=exited)
    a5f544c5365a
    6c0af66c3052
    [root@master ~]#docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    2a2bb4fc9904 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp peaceful_noether
  19. 批量删除所有容器

    docker rm -f $(docker ps -a -q)

    示例

    [root@master ~]#docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    0f2c3cfc3bf7 nginx "/docker-entrypoint.…" 33 seconds ago Up 32 seconds 80/tcp heuristic_clarke
    2cad8aef4f26 nginx "/docker-entrypoint.…" 34 seconds ago Exited (0) 19 seconds ago distracted_kepler
    7a56563e2d3b nginx "/docker-entrypoint.…" 35 seconds ago Up 35 seconds 80/tcp inspiring_gould
    2a2bb4fc9904 nginx "/docker-entrypoint.…" 4 minutes ago Exited (0) 4 seconds ago peaceful_noether
    [root@master ~]#docker rm -f $(docker ps -a -q)
    0f2c3cfc3bf7
    2cad8aef4f26
    7a56563e2d3b
    2a2bb4fc9904
    [root@master ~]#docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  20. 指定容器DNS

    DNS服务,默认采用宿主机的dns地址

    一是将dns地址配置在宿主机

    二是将参数配置在docker启动脚本里面 --dns=1.1.1.1

    示例

    [root@master ~]#docker run -it --rm --dns 114.114.114.114 alpine sh
    / # cat /etc/resolv.conf
    nameserver 114.114.114.114
    / #
  21. 其他命令

    docker update 容器 --cpus 2 #更新容器配置信息
    docker events #获取dockerd实时事件
    docker wait 容器ID #显示容器退出状态码
    docker commit 容器ID 镜像名称 #将容器提交为镜像
    [root@master ~]#docker stop e8c0f56cfaa3
    e8c0f56cfaa3
    [root@master ~]#docker wait e8c0f56cfaa3
    0
    docker diff 容器ID #检查容器更改过的文件或目录

三、制作nginx镜像,详解分层,为什么要分层,如何分层

利用dockerfile制作镜像

编写dockerfile

FROM centos:7.9.2009
RUN yum install -y make gcc gcc-c++ pcre pcre-devel openssl openssl-devel zlib zlib-devel perl-ExtUtils-Embed net-tools iotop iproute
ADD nginx-1.18.0.tar.gz /usr/local/src/
RUN cd /usr/local/src/nginx-1.18.0 && ./configure --prefix=/usr/local/nginx --with-http_sub_module && make && make install
ADD nginx.conf /usr/local/nginx/conf/nginx.conf
RUN useradd -s /sbin/nologin nginx
RUN ln -s /usr/local/nginx/sbin/nginx /usr/sbin/nginx
RUN echo 'test nginx' > /usr/local/nginx/html/index.html
EXPOSE 80 443
CMD ["nginx"]
#CMD ["nginx","-g", "daemon off;"]

准备nginx.conf

[root@master centos7.9]#egrep -v '^\s*#|^$' nginx.conf
user nginx;
worker_processes auto;
daemon off;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

准备nginx源码

查看文件

[root@master centos7.9]#tree
.
├── Dockerfile
├── nginx-1.18.0.tar.gz
└── nginx.conf
0 directories, 3 files

执行构建

[root@master centos7.9]#docker build -t nginx:v1 .
Sending build context to Docker daemon 1.047MB
Step 1/10 : FROM centos:7.9.2009
---> eeb6ee3f44bd
Step 2/10 : RUN yum install -y make gcc gcc-c++ pcre pcre-devel openssl openssl-devel zlib zlib-devel perl-ExtUtils-Embed net-tools iotop iproute
---> Using cache
---> dd79de40da29
Step 3/10 : ADD nginx-1.18.0.tar.gz /usr/local/src/
---> Using cache
---> f35253096dcd
Step 4/10 : RUN cd /usr/local/src/nginx-1.18.0 && ./configure --prefix=/usr/local/nginx --with-http_sub_module && make && make install
---> Using cache
---> d0ccc11277b9
Step 5/10 : ADD nginx.conf /usr/local/nginx/conf/nginx.conf
---> Using cache
---> 95b547dfc9c5
Step 6/10 : RUN useradd -s /sbin/nologin nginx
---> Using cache
---> 7783182f1d05
Step 7/10 : RUN ln -s /usr/local/nginx/sbin/nginx /usr/sbin/nginx
---> Using cache
---> 6f9d4e28b344
Step 8/10 : RUN echo 'test nginx' > /usr/local/nginx/html/index.html
---> Using cache
---> 908830530787
Step 9/10 : EXPOSE 80 443
---> Using cache
---> a6c4f096a1bf
Step 10/10 : CMD ["nginx"]
---> Using cache
---> d2eaa79439ec
Successfully built d2eaa79439ec
Successfully tagged nginx:v1

查看镜像

[root@master ~]#docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 d2eaa79439ec 11 minutes ago 555MB #制作生成的nginx镜像
centos7.9-base v1 a2d812775cb5 About an hour ago 503MB
alpine latest 9c6f07244728 2 days ago 5.54MB
ubuntu 20.04 3bc6e9f30f51 10 days ago 72.8MB
hello-world latest feb5d9fea6a5 10 months ago 13.3kB
centos 7.9.2009 eeb6ee3f44bd 11 months ago 204MB

从镜像启动容器

[root@master ~]#docker run -it -d -p 80:80 nginx:v1 nginx
3750c55ac16f708577f4ee1370a2665f57bc5a08c9097946207b3c7a3bcc1681
[root@master ~]#docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3750c55ac16f nginx:v1 "nginx" 5 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp, 443/tcp dazzling_herschel

查看宿主机80端口开启

[root@master centos7.9]#hostname -I
10.0.0.12 172.17.0.1
[root@master centos7.9]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6010 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6011 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6013 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:35391 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:41215 0.0.0.0:*
LISTEN 0 64 0.0.0.0:43489 0.0.0.0:*
LISTEN 0 64 0.0.0.0:2049 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:57319 0.0.0.0:*
LISTEN 0 128 127.0.0.1:39435 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:111 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 4096 [::]:55385 [::]:*
LISTEN 0 128 [::1]:6010 [::]:*
LISTEN 0 128 [::1]:6011 [::]:*
LISTEN 0 4096 [::]:54013 [::]:*
LISTEN 0 128 [::1]:6013 [::]:*
LISTEN 0 64 [::]:2049 [::]:*
LISTEN 0 4096 [::]:37481 [::]:*
LISTEN 0 64 [::]:45259 [::]:*
LISTEN 0 128 [::1]:39435 [::]:*
LISTEN 0 4096 [::]:111 [::]:*
LISTEN 0 4096 [::]:80 [::]:*

访问web界面

镜像分层

分层机制

Docker镜像是分层构建的,Dockerfile中每条指定都会新建一个层。以下面Dockerfile指令为例:

FROM ubuntu:20.04 #基础镜像
COPY . /app #复制文件
RUN make /app #编译文件
CMD python /app/app.py #入口文件

以上四条指令,在每一层上只记录本层所做的更改,而且这些层是只读层。当启动一个容器,Docker只会在最顶部添加读写层,在容器内作的所有更改(写日志、修改、删除文件等,都保存到读写层内),一般称该层为容器层,如下图所示:

事实上,容器(container)和镜像(image)的最主要区别就是容器加上了顶层的读写层。所有对容器的修改都发生在此层,镜像并不会被修改,也即前面说的 COW(copy-on-write)技术。容器需要读取某个文件时,直接从底部只读层去读即可,而如果需要修改某文件,则将该文件拷贝到顶部读写层进行修改,只读层保持不变。

每个容器都有自己的读写层,因此多个容器可以使用同一个镜像,另外容器被删除时,其对应的读写层也会被删除,如果希望多个容器共享或者持久化数据,可以使用 Docker volume。

UnionFS(联合文件系统)

(1)Union文件系统(UnionFS)是一种分层的、轻量级的、高性能的文件系统,它是Docker镜像的基础,并且支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂在到同一个虚拟文件系统下。
(2)镜像可以通过分层来进行继承,基于基础镜像,可以制作各种具体的应用镜像。

Union文件系统的特性:一次性同时加载多个文件系统,但是从外面来看,只能看到一个文件系统;联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有地层的文件和目录。

Docker镜像加载原理

Docker的镜像是由一层一层的文件系统组成,也就是以UnionFS(联合文件系统)堆叠构成。

rootfs(root file system)包含的是典型Linux系统中的/dev、/proc、/bin、/etc等标准目录和文件,其实rootfs就是各种不同的操作系统发行版,比如Ubuntu、Centos等等。

bootfs(boot file system)主要包含bootloader和kernel、bootloader主要是引导加载kernel、Linux刚启动时候加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成后整个内核就在内存中了,内存的使用权由bootfs转交给内核,此时系统也会写在bootfs。至此,我们就比较容易理解docker容器其实就是一个简易版的Linux环境,它包含root用户权限、进程空间、用户空间和网络空间、以及运行在它上面的应用程序。

注意:
(1)如上图所示,Docker镜像层都是只读的,容器层是可写的。当容器启动时,一个新的可写层被加载到镜像顶部,这一层通常被称作“容器层”,“容器层”之下的都叫做“镜像层”。
(2)对容器的所有更改(无论添加、删除、还是修改文件)都只会发生在容器层中。上图中只有透明的writable Container是暴露给用户的。

Docker采用镜像分层的好处

镜像分层最大的好处:资源共享,方便复制迁移,容易实现资源复用。比如说多个镜像从相同的base镜像构建而来,那么Docker Host只需在磁盘上保存一份base镜像;同时内存中只需要加载一份base镜像,就可以为所有容器提供服务了,更有趣的是镜像的每一层都可以被共享。

因此,Docker采用镜像分层的好处主要体现在以下三个方面:

更轻量

  • 镜像大小:所需空间更小
  • 部署:更有利于大规模部署

更高效

  • 计算:轻量、无需额外开销
  • 存储:系统盘aufs/dm/overlayfs;数据盘olume
  • 网络:宿主机网络,NS隔离

更敏捷、更灵活

  • 分层的存储和包管理,devops理念;
  • 支持多网络配置

Docker镜像分层优化

参考:https://www.techug.com/post/several-methods-of-optimizing-docker-image/

  • 基础镜像小

    使用alpine镜像代替centos、ubuntu等镜像

  • 层级尽量少

    在编写Dockerfile时,将一些指令合并,减少最终镜像层数

  • 去除不必要

    清除yum/apt缓存,源码包

  • 复用镜像层

    在Dockefile中将不常改动,但常用的指令放在前面去执行,如添加镜像仓库,安装基本的编译工具gcc、autoconf、make、zlib 等,这样后面构建用到的所有镜像都不会再重新安装

  • 分阶段构建

    将构建过程分解,分成多个阶段来执行,后面的或者最终的构建可以使用前面构建的结果,而不需要所有的构建都包含到最终的镜像中

四、安装docker官方registry实现镜像分发

单机registry仓库

  • 安装registry
# 下载registry镜像
docker pull registry:2.6
# 创建用户和密码,注意2.7版本已移除htpasswd命令
mkdir -pv /docker/auth
docker run --entrypoint htpasswd registry:2.6 -Bbn admin 123456 > /docker/auth/htpasswd
# 启动registry
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /docker/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry:2.6
  • 配置仓库连接信息
# 各服务器添加registry IP和端口号
[root@docker-master1 ~]#vim /etc/docker/daemon.json
{"insecure-registries":["10.0.0.12:5000"]}
# 重启服务
[root@docker-master1 ~]#systemctl restart docker
  • 验证端口和容器
# 查看容器
[root@docker-master1 ~]#docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48cf4397006f registry:2.6 "/entrypoint.sh /etc…" About an hour ago Up About an hour 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp registry
# 查看5000端口
[root@docker-master1 ~]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6010 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6011 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:5000 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:111 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 [::1]:6010 [::]:*
LISTEN 0 128 [::1]:6011 [::]:*
LISTEN 0 4096 [::]:5000 [::]:*
LISTEN 0 4096 [::]:111 [::]:*
  • 登录仓库
# node1连接
[root@docker-node1 ~]#docker login 10.0.0.12:5000
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded

镜像分发

  • master节点上传镜像

    # 镜像标记tag
    [root@docker-master1 ~]#docker tag nginx:v1 10.0.0.12:5000/nginx:v1
    #查看带tag镜像
    [root@docker-master1 ~]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    10.0.0.12:5000/nginx v1 4394cb54ed26 23 hours ago 555MB #带tag镜像
    nginx v1 4394cb54ed26 23 hours ago 555MB
    centos7.9-base v1 a2d812775cb5 26 hours ago 503MB
    alpine latest 9c6f07244728 3 days ago 5.54MB
    nginx latest b692a91e4e15 11 days ago 142MB
    ubuntu latest df5de72bdb3b 11 days ago 77.8MB
    ubuntu 20.04 3bc6e9f30f51 11 days ago 72.8MB
    hello-world latest feb5d9fea6a5 10 months ago 13.3kB
    centos 7.9.2009 eeb6ee3f44bd 11 months ago 204MB
    registry 2.6 10b45af23ff3 2 years ago 28.5MB
    # 上传带tag镜像
    [root@docker-master1 ~]#docker push 10.0.0.12:5000/nginx:v1
    The push refers to repository [10.0.0.12:5000/nginx]
    c0f7036fdc0b: Pushed
    ac9d717b8984: Pushed
    1b260a25fd7b: Pushed
    247d1182f20a: Pushed
    6e643f0e9728: Pushed
    b6d618588906: Pushed
    84fdb1e06bb6: Pushed
    174f56854903: Pushed
    v1: digest: sha256:5eda4f676ea0abac1903049679cf0def5bed6e51e01b147dac3ce92640f8d00d size: 1994
  • node节点下载镜像

    # 登录docker registry
    [root@docker-node1 ~]#docker login 10.0.0.12:5000
    Username: admin
    Password:
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    Login Succeeded
    # 查看镜像
    [root@docker-node1 ~]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    # 下载10.0.0.12:5000/nginx:v1镜像
    [root@docker-node1 ~]#docker pull 10.0.0.12:5000/nginx:v1
    v1: Pulling from nginx
    2d473b07cdd5: Pull complete
    d7e01e79be23: Pull complete
    79e1a8dc244c: Pull complete
    7de199fd7606: Pull complete
    fc6c8af824ab: Pull complete
    c8aaed017572: Pull complete
    c874feb5eba1: Pull complete
    6fb513e8141a: Pull complete
    Digest: sha256:5eda4f676ea0abac1903049679cf0def5bed6e51e01b147dac3ce92640f8d00d
    Status: Downloaded newer image for 10.0.0.12:5000/nginx:v1
    10.0.0.12:5000/nginx:v1
    # 验证镜像下载成功
    [root@docker-node1 ~]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    10.0.0.12:5000/nginx v1 4394cb54ed26 23 hours ago 555MB
  • 从下载的镜像启动容器

    [root@docker-node1 ~]#hostname -I
    10.0.0.22 172.17.0.1
    [root@docker-node1 ~]#docker run -d -it -p 80:80 --name nginx 10.0.0.12:5000/nginx:v1
    6be0f54dae7c3c73f38000350a3dbb00cc4f6af5343a276a35f264eb3b203e60
  • 访问测试

五、安装docker镜像仓库harbor,并实现高可用

harbor高可用方式主要有基于共享存储和基于镜像复制的两种方法

双主镜像复制高可用安装方法如下:

架构

client
10.0.0.42
haproxy
10.0.0.12
harbor-master
10.0.0.22
harbor-backup
10.0.0.32

安装harbor-master服务器(10.0.0.22)

安装docker

#! /bin/bash
apt update
apt install \
ca-certificates \
curl \
gnupg \
lsb-release
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sed -i '/GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"/c GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 cgroup_enable=memory swapaccount=1"' /etc/default/grub
update-grub
reboot

安装docker-compose

使用pip方式安装

# 安装pip
apt install python3-pip -y
# 安装docker-compose
pip install docker-compose

安装harbor仓库

参考:https://goharbor.io/docs/2.5.0/install-config/download-installer/

  1. 下载离线安装包

    wget https://github.com/goharbor/harbor/releases/download/v2.4.3/harbor-offline-installer-v2.4.3.tgz

  2. 解压harbor

    tar xvf harbor-offline-installer-v2.4.3.tgz -C /usr/local/src

  3. 配置harbor.yml文件

    cd /usr/local/src/harbor
    egrep -v '^\s*#|^$' harbor.yml.tmpl > harbor.yml

    根据实际修改hostnanme、harbor_admin_password、database等

    [root@harbor1 harbor]#cat harbor.yml
    hostname: 10.0.0.22
    http:
    port: 80
    #https:
    #port: 443
    #certificate: /your/certificate/path
    #private_key: /your/private/key/path
    harbor_admin_password: Harbor12345
    database:
    password: root123
    max_idle_conns: 100
    max_open_conns: 900
    data_volume: /data
    trivy:
    ignore_unfixed: false
    skip_update: false
    offline_scan: false
    insecure: false
    jobservice:
    max_job_workers: 10
    notification:
    webhook_job_max_retry: 10
    chart:
    absolute_url: disabled
    log:
    level: info
    local:
    rotate_count: 50
    rotate_size: 200M
    location: /var/log/harbor
    _version: 2.4.0
    proxy:
    http_proxy:
    https_proxy:
    no_proxy:
    components:
    - core
    - jobservice
    - trivy
  4. 执行harbor安装脚本

    [root@harbor1 harbor]#./install.sh
    [Step 0]: checking if docker is installed ...
    Note: docker version: 20.10.17
    [Step 1]: checking docker-compose is installed ...
    Note: docker-compose version: 1.29.2
    [Step 2]: loading Harbor images ...
    Loaded image: goharbor/trivy-adapter-photon:v2.4.3
    Loaded image: goharbor/redis-photon:v2.4.3
    Loaded image: goharbor/nginx-photon:v2.4.3
    Loaded image: goharbor/notary-signer-photon:v2.4.3
    Loaded image: goharbor/prepare:v2.4.3
    Loaded image: goharbor/harbor-registryctl:v2.4.3
    Loaded image: goharbor/harbor-log:v2.4.3
    Loaded image: goharbor/harbor-jobservice:v2.4.3
    Loaded image: goharbor/harbor-exporter:v2.4.3
    Loaded image: goharbor/registry-photon:v2.4.3
    Loaded image: goharbor/notary-server-photon:v2.4.3
    Loaded image: goharbor/harbor-portal:v2.4.3
    Loaded image: goharbor/harbor-core:v2.4.3
    Loaded image: goharbor/harbor-db:v2.4.3
    Loaded image: goharbor/chartmuseum-photon:v2.4.3
    [Step 3]: preparing environment ...
    [Step 4]: preparing harbor configs ...
    prepare base dir is set to /usr/local/src/harbor
    WARNING:root:WARNING: HTTP protocol is insecure. Harbor will deprecate http protocol in the future. Please make sure to upgrade to https
    Generated configuration file: /config/portal/nginx.conf
    Generated configuration file: /config/log/logrotate.conf
    Generated configuration file: /config/log/rsyslog_docker.conf
    Generated configuration file: /config/nginx/nginx.conf
    Generated configuration file: /config/core/env
    Generated configuration file: /config/core/app.conf
    Generated configuration file: /config/registry/config.yml
    Generated configuration file: /config/registryctl/env
    Generated configuration file: /config/registryctl/config.yml
    Generated configuration file: /config/db/env
    Generated configuration file: /config/jobservice/env
    Generated configuration file: /config/jobservice/config.yml
    Generated and saved secret to file: /data/secret/keys/secretkey
    Successfully called func: create_root_cert
    Generated configuration file: /compose_location/docker-compose.yml
    Clean up the input dir
    [Step 5]: starting Harbor ...
    Creating network "harbor_harbor" with the default driver
    Creating harbor-log ... done
    Creating harbor-db ... done
    Creating redis ... done
    Creating registry ... done
    Creating registryctl ... done
    Creating harbor-portal ... done
    Creating harbor-core ... done
    Creating harbor-jobservice ... done
    Creating nginx ... done
    ✔ ----Harbor has been installed and started successfully.----

    安装完成后会生成docker-compose.yml文件

    [root@harbor1 harbor]#ls /usr/local/src/harbor/
    LICENSE common common.sh docker-compose.yml harbor.v2.4.3.tar.gz harbor.yml harbor.yml.tmpl install.sh prepare
  5. 若更新配置,可执行prepare

    # 修改harbor.yml配置文件
    [root@harbor1 harbor]# vim /usr/local/src/harbor/harbor.yml
    # 执行prepare
    [root@harbor1 harbor]#/usr/local/src/harbor/prepare
  6. 查看本地镜像

    [root@harbor1 harbor]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    goharbor/harbor-exporter v2.4.3 776ac6ee91f4 13 days ago 81.5MB
    goharbor/chartmuseum-photon v2.4.3 f39a9694988d 13 days ago 172MB
    goharbor/redis-photon v2.4.3 b168e9750dc8 13 days ago 154MB
    goharbor/trivy-adapter-photon v2.4.3 a406a715461c 13 days ago 251MB
    goharbor/notary-server-photon v2.4.3 da89404c7cf9 13 days ago 109MB
    goharbor/notary-signer-photon v2.4.3 38468ac13836 13 days ago 107MB
    goharbor/harbor-registryctl v2.4.3 61243a84642b 13 days ago 135MB
    goharbor/registry-photon v2.4.3 9855479dd6fa 13 days ago 77.9MB
    goharbor/nginx-photon v2.4.3 0165c71ef734 13 days ago 44.4MB
    goharbor/harbor-log v2.4.3 57ceb170dac4 13 days ago 161MB
    goharbor/harbor-jobservice v2.4.3 7fea87c4b884 13 days ago 219MB
    goharbor/harbor-core v2.4.3 d864774a3b8f 13 days ago 197MB
    goharbor/harbor-portal v2.4.3 85f00db66862 13 days ago 53.4MB
    goharbor/harbor-db v2.4.3 7693d44a2ad6 13 days ago 225MB
    goharbor/prepare v2.4.3 c882d74725ee 13 days ago 268MB
  7. 查看端口

    [root@harbor1 harbor]#ss -ntl
    State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
    LISTEN 0 64 0.0.0.0:2049 0.0.0.0:*
    LISTEN 0 4096 0.0.0.0:39331 0.0.0.0:*
    LISTEN 0 4096 0.0.0.0:60265 0.0.0.0:*
    LISTEN 0 4096 127.0.0.1:1514 0.0.0.0:*
    LISTEN 0 64 0.0.0.0:38541 0.0.0.0:*
    LISTEN 0 4096 0.0.0.0:111 0.0.0.0:*
    LISTEN 0 4096 0.0.0.0:80 0.0.0.0:*
    LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
    LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
    LISTEN 0 4096 0.0.0.0:40505 0.0.0.0:*
    LISTEN 0 128 127.0.0.1:6010 0.0.0.0:*
    LISTEN 0 64 [::]:2049 [::]:*
    LISTEN 0 4096 [::]:39143 [::]:*
    LISTEN 0 4096 [::]:44427 [::]:*
    LISTEN 0 64 [::]:41293 [::]:*
    LISTEN 0 4096 [::]:111 [::]:*
    LISTEN 0 4096 [::]:80 [::]:*
    LISTEN 0 128 [::]:22 [::]:*
    LISTEN 0 4096 [::]:49049 [::]:*
    LISTEN 0 128 [::1]:6010
  8. Web登录Harbor管理界面

    用户名:admin

    密码:Harbor12345

  9. 进入管理界面首页

镜像上传

  1. 配置docker文件,实现连接harbor仓库

    注意:若使用HTTP连接harbor仓库必须进行如下设置

    # 添加harbor仓库信息
    [root@harbor1 harbor]#cat /etc/docker/daemon.json
    {"insecure-registries":["10.0.0.22:80"]}
    # 重启docker
    [root@harbor1 harbor]#systemctl restart docker
    # 停止harbor
    [root@harbor1 harbor]#docker-compose down -v
    # 启动harbor
    [root@harbor1 harbor]#docker-compose up -d
  2. 登录harbor

    [root@harbor1 harbor]#docker login 10.0.0.22:80
    Username: admin
    Password:
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    Login Succeeded
  3. 上传镜像

    • 导入镜像
    # 先将前期nginx镜像导出
    docker save test-nginx:v1 > /opt/test-nginx.tar.gz
    # 导入nginx镜像
    [root@harbor1 harbor]#docker load < /opt/test-nginx.tar.gz
    92a4e8a3140f: Loading layer [==================================================>] 83.87MB/83.87MB
    e3257a399753: Loading layer [==================================================>] 62.04MB/62.04MB
    3a89c8160a43: Loading layer [==================================================>] 3.072kB/3.072kB
    f91d0987b144: Loading layer [==================================================>] 4.096kB/4.096kB
    bdc7a32279cc: Loading layer [==================================================>] 3.584kB/3.584kB
    b539cf60d7bb: Loading layer [==================================================>] 7.168kB/7.168kB
    859e93b7b349: Loading layer [==================================================>] 15.87kB/15.87kB
    Loaded image: test-nginx:v1
    • 验证镜像导入成功
    [root@harbor1 harbor]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    test-nginx v1 f88af8dcd86c 14 minutes ago 142MB
    nginx latest b692a91e4e15 12 days ago 142MB
    goharbor/harbor-exporter v2.4.3 776ac6ee91f4 13 days ago 81.5MB
    goharbor/chartmuseum-photon v2.4.3 f39a9694988d 13 days ago 172MB
    goharbor/redis-photon v2.4.3 b168e9750dc8 13 days ago 154MB
    • 镜像打tag,即修改images名称,须符合harbor仓库格式,格式为Harbor IP:Port/项目名/image名称:版本号,否则镜像无法上传至harbor仓库
    [root@harbor1 harbor]#docker tag test-nginx:v1 10.0.0.22:80/nginx/test-nginx:v1
    [root@harbor1 harbor]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    test-nginx v1 f88af8dcd86c 30 minutes ago 142MB
    10.0.0.22:80/nginx/test-nginx v1 f88af8dcd86c 30 minutes ago 142MB
    nginx latest b692a91e4e15 12 days ago 142MB
    goharbor/harbor-exporter v2.4.3 776ac6ee91f4 13 days ago 81.5MB
    goharbor/chartmuseum-photon v2.4.3 f39a9694988d 13 days ago 172MB
    • 在harbor管理界面创建项目(必须先创建项目,否则镜像将上传失败)
    • 上传镜像至harbor仓库
    [root@harbor1 harbor]#docker push 10.0.0.22:80/nginx/test-nginx:v1
    The push refers to repository [10.0.0.22:80/nginx/test-nginx]
    859e93b7b349: Pushed
    b539cf60d7bb: Pushed
    bdc7a32279cc: Pushed
    f91d0987b144: Pushed
    3a89c8160a43: Pushed
    e3257a399753: Pushed
    92a4e8a3140f: Pushed
    v1: digest: sha256:942872299c16e7fb0eb0b09e42ccdfc30f2f005674a56a7dfa663bfd5e55978f size: 1777
    • 登录harbor web界面验证镜像上传成功

镜像下载

  1. 配置登录harbor仓库连接信息

    # 添加harbor仓库信息
    [root@harbor2 harbor]#cat /etc/docker/daemon.json
    {"insecure-registries":["10.0.0.22:80"]}
    # 重启docker
    [root@harbor2 harbor]#systemctl restart docker
  2. 登录harbor

    [root@harbor2 opt]#docker login 10.0.0.22:80
    Username: admin
    Password:
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    Login Succeeded
  3. 使用docker pull下载镜像

    [root@harbor2 opt]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    # 下载镜像
    [root@harbor2 opt]#docker pull 10.0.0.22:80/nginx/test-nginx:v1
    v1: Pulling from nginx/test-nginx
    1efc276f4ff9: Pull complete
    baf2da91597d: Pull complete
    05396a986fd3: Pull complete
    6a17c8e7063d: Pull complete
    27e0d286aeab: Pull complete
    b1349eea8fc5: Pull complete
    f588f8790de9: Pull complete
    Digest: sha256:942872299c16e7fb0eb0b09e42ccdfc30f2f005674a56a7dfa663bfd5e55978f
    Status: Downloaded newer image for 10.0.0.22:80/nginx/test-nginx:v1
    10.0.0.22:80/nginx/test-nginx:v1
    # 查看下载镜像
    [root@harbor2 opt]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    10.0.0.22:80/nginx/test-nginx v1 f88af8dcd86c 48 minutes ago 142MB
  4. 验证从镜像启动容器

    [root@harbor2 opt]#docker run -d -p 80:80 10.0.0.22:80/nginx/test-nginx:v1
    61b60f5c14f70b29745f7ed6198d34918d90330bea25e3cc177cee0bfc01a5f9
    [root@harbor2 opt]#hostname -I
    10.0.0.32 172.17.0.1
  5. 验证web访问

安装harbor-backup服务器(10.0.0.32)

方法见harbor-master

安装完成后等web管理界面添加nginx项目

配置双主镜像复制

harbor-master配置

  • 创建backup仓库

    系统管理--仓库管理--新建目标

    添加backup仓库信息

  • 查看仓库信息

  • 添加复制管理规则

    系统管理--复制管理--新建规则

    添加规则

  • 查看复制管理信息

harbor-backup配置

  • 创建master仓库

    系统管理--仓库管理--新建目标

  • 查看仓库信息

  • 添加复制管理规则

  • 查看复制管理信息

验证master仓库镜像同步至backup仓库

  • 上传镜像至harbor-master仓库

    [root@harbor-master ~]#docker push 10.0.0.22:80/nginx/test-nginx:v1
    The push refers to repository [10.0.0.22:80/nginx/test-nginx]
    859e93b7b349: Layer already exists
    b539cf60d7bb: Layer already exists
    bdc7a32279cc: Layer already exists
    f91d0987b144: Layer already exists
    3a89c8160a43: Layer already exists
    e3257a399753: Layer already exists
    92a4e8a3140f: Layer already exists
    v1: digest: sha256:942872299c16e7fb0eb0b09e42ccdfc30f2f005674a56a7dfa663bfd5e55978f size: 1777
  • 查看harbor-master仓库上传镜像

  • 查看复制任务事件

  • 查看harbor-backup仓库镜像

  • 从harbor-backup仓库中pull镜像

    [root@harbor-backup ~]#docker pull 10.0.0.32:80/nginx/test-nginx:v1
    v1: Pulling from nginx/test-nginx
    Digest: sha256:942872299c16e7fb0eb0b09e42ccdfc30f2f005674a56a7dfa663bfd5e55978f
    Status: Downloaded newer image for 10.0.0.32:80/nginx/test-nginx:v1
    10.0.0.32:80/nginx/test-nginx:v1
    [root@harbor-backup ~]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    10.0.0.32:80/nginx/test-nginx v1 f88af8dcd86c 16 hours ago 142MB
    test-nginx v1 f88af8dcd86c 16 hours ago 142MB
    goharbor/harbor-exporter v2.4.3 776ac6ee91f4 2 weeks ago 81.5MB

验证backup仓库镜像同步至master仓库

  • 上传镜像至harbor-backup仓库

    [root@harbor-backup ~]#docker push 10.0.0.32:80/nginx/test2-nginx:v1
    The push refers to repository [10.0.0.32:80/nginx/test2-nginx]
    859e93b7b349: Pushed
    b539cf60d7bb: Pushed
    bdc7a32279cc: Pushed
    f91d0987b144: Pushed
    3a89c8160a43: Pushed
    e3257a399753: Pushed
    92a4e8a3140f: Pushed
    v1: digest: sha256:942872299c16e7fb0eb0b09e42ccdfc30f2f005674a56a7dfa663bfd5e55978f size: 1777
  • 查看harbor-backup仓库镜像

  • 查看复制任务事件

  • 查看harbor-master仓库镜像

  • 测试从harbor-master仓库中pull镜像

    [root@harbor-master ~]#docker pull 10.0.0.22:80/nginx/test2-nginx:v1
    v1: Pulling from nginx/test2-nginx
    Digest: sha256:942872299c16e7fb0eb0b09e42ccdfc30f2f005674a56a7dfa663bfd5e55978f
    Status: Downloaded newer image for 10.0.0.22:80/nginx/test2-nginx:v1
    10.0.0.22:80/nginx/test2-nginx:v1
    [root@harbor-master ~]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    10.0.0.22:80/nginx/test-nginx v1 f88af8dcd86c 16 hours ago 142MB
    10.0.0.22:80/nginx/test2-nginx v1 f88af8dcd86c 16 hours ago 142MB
    test-nginx v1 f88af8dcd86c 16 hours ago 142MB
    nginx latest b692a91e4e15 13 days ago 142MB

安装haproxy服务器(10.0.0.12)

安装haproxy

  • apt安装

    apt install haproxy -y

  • 修改haproxy.cfg配置

    [root@haproxy ~]#cat /etc/haproxy/haproxy.cfg
    ...
    # 添加以下配置
    listen stats
    mode http
    bind 0.0.0.0:9999
    stats enable
    log global
    stats uri /haproxy-status
    stats auth haadmin:123456
    listen web_harbor
    bind 10.0.0.12:80
    mode http
    log global
    balance source # 源地址hash
    server 10.0.0.22 10.0.0.22:80 check inter 3s fall 3 rise 5 #master仓库
    server 10.0.0.32 10.0.0.32:80 check inter 3s fall 3 rise 5 #backup仓库
  • 重启服务

    systemctl restart haproxy

  • 查看状态页

验证测试

  • client(10.0.0.42)配置

    # 添加LB连接信息
    [root@client ~]#cat /etc/docker/daemon.json
    {"insecure-registries":["10.0.0.12:80"]}
    # 重启docker
    [root@client ~]#systemctl restart docker
    # 登录harbor仓库
    [root@client ~]#docker login 10.0.0.12:80
    Username: admin
    Password:
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    Login Succeeded
  • 下载镜像

    # 下载test-nginx镜像
    [root@client ~]#docker pull 10.0.0.12:80/nginx/test-nginx:v1
    v1: Pulling from nginx/test-nginx
    1efc276f4ff9: Pull complete
    baf2da91597d: Pull complete
    05396a986fd3: Pull complete
    6a17c8e7063d: Pull complete
    27e0d286aeab: Pull complete
    b1349eea8fc5: Pull complete
    f588f8790de9: Pull complete
    Digest: sha256:942872299c16e7fb0eb0b09e42ccdfc30f2f005674a56a7dfa663bfd5e55978f
    Status: Downloaded newer image for 10.0.0.12:80/nginx/test-nginx:v1
    10.0.0.12:80/nginx/test-nginx:v1
    # 下载test2-nginx镜像
    [root@client ~]#docker pull 10.0.0.12:80/nginx/test2-nginx:v1
    v1: Pulling from nginx/test2-nginx
    Digest: sha256:942872299c16e7fb0eb0b09e42ccdfc30f2f005674a56a7dfa663bfd5e55978f
    Status: Downloaded newer image for 10.0.0.12:80/nginx/test2-nginx:v1
    10.0.0.12:80/nginx/test2-nginx:v1
    # 查看镜像
    [root@client ~]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    10.0.0.12:80/nginx/test-nginx v1 f88af8dcd86c 17 hours ago 142MB
    10.0.0.12:80/nginx/test2-nginx v1 f88af8dcd86c 17 hours ago 142MB
  • 上传镜像

    [root@client ~]#docker push 10.0.0.12:80/nginx/alpine-test:v1
    The push refers to repository [10.0.0.12:80/nginx/alpine-test]
    994393dc58e7: Pushed
    v1: digest: sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870 size: 528

    查看harbor-master仓库

    查看harbor-backup仓库

高可用验证

模拟master故障

  • client下载镜像

    [root@client ~]#docker pull 10.0.0.12:80/nginx/test-nginx:v1
    v1: Pulling from nginx/test-nginx
    1efc276f4ff9: Pull complete
    baf2da91597d: Pull complete
    05396a986fd3: Pull complete
    6a17c8e7063d: Pull complete
    27e0d286aeab: Pull complete
    b1349eea8fc5: Pull complete
    f588f8790de9: Pull complete
    Digest: sha256:942872299c16e7fb0eb0b09e42ccdfc30f2f005674a56a7dfa663bfd5e55978f
    Status: Downloaded newer image for 10.0.0.12:80/nginx/test-nginx:v1
    10.0.0.12:80/nginx/test-nginx:v1
  • 查看镜像

    [root@client ~]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    10.0.0.12:80/nginx/test-nginx v1 f88af8dcd86c 17 hours ago 142MB
  • 从镜像启动容器

    [root@client ~]#docker run -d -it -p 80:80 10.0.0.12:80/nginx/test-nginx:v1
    aa1099ed0f82d0b685c84cbf4accd8d790fa9a1631c49fa11cd8e52ccc31e8ca

    访问验证

模拟backup故障

  • client下载镜像

    [root@client ~]#docker pull 10.0.0.12:80/nginx/alpine-test:v1
    v1: Pulling from nginx/alpine-test
    213ec9aee27d: Pull complete
    Digest: sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870
    Status: Downloaded newer image for 10.0.0.12:80/nginx/alpine-test:v1
    10.0.0.12:80/nginx/alpine-test:v1
  • 查看镜像

    [root@client ~]#docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    10.0.0.12:80/nginx/test-nginx v1 f88af8dcd86c 17 hours ago 142MB
    10.0.0.12:80/nginx/alpine-test v1 9c6f07244728 5 days ago 5.54MB
  • 从镜像启动容器

    [root@client ~]#docker run -it 10.0.0.12:80/nginx/alpine-test:v1 sh
    / # ls
    bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var

注意:故障若导致harbor仓库镜像不一致时,需要手动执行一次同步操作

系统管理--复制管理--选择管理规则--复制--确认,可在任务事件中查看执行结果

六、使用docker运行mysql数据库,并将数据保存在磁盘上,确保数据不丢失;

在宿主机新建目录

mkdir -pv /data/mysql

启动mysql,将宿主机/data/mysql目录挂载至容器/var/lib/mysql

docker run -d -it --name mysql -p 3306:3306 -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql

查看端口

[root@client mysql]#ss -ntlp|grep 3306
LISTEN 0 4096 0.0.0.0:3306 0.0.0.0:* users:(("docker-proxy",pid=9174,fd=4))
LISTEN 0 4096 [::]:3306 [::]:* users:(("docker-proxy",pid=9180,fd=4))

新建test数据库

[root@client mysql]#mysql -uroot -p123456 -h10.0.0.42
mysql> create database test;
Query OK, 1 row affected (0.05 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.01 sec)

删除容器

[root@client mysql]#docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c1c6feb76879 mysql "docker-entrypoint.s…" 11 minutes ago Up 11 minutes 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
[root@client mysql]#docker rm -f mysql
mysql
[root@client mysql]#docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

查看宿主机目录,文件未被删除

[root@client mysql]#ls /data/mysql/
'#ib_16384_0.dblwr' '#innodb_temp' binlog.000002 ca-key.pem client-key.pem ibtmp1 mysql.sock public_key.pem sys undo_002
'#ib_16384_1.dblwr' auto.cnf binlog.index ca.pem ib_buffer_pool mysql performance_schema server-cert.pem test
'#innodb_redo' binlog.000001 c1c6feb76879.err client-cert.pem ibdata1 mysql.ibd private_key.pem server-key.pem undo_001

重新运行mysql,test数据库正常加载

[root@client mysql]#docker run -d -it --name mysql -p 3306:3306 -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql
a064adecfc6a73530625fad198d8a010dda8b680ceaff492a67ae5293028d0c2
[root@client mysql]#mysql -uroot -p123456 -h10.0.0.42
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)

七、使用docker限制运行的容器的资源;

内存限制

  • --oom-score-adj

    宿主机 kernel对进程使用的内存进行评分,评分最高的将被宿主机内核kill掉(越低越不容易被kill),可以指定一个容器的评分为较低的负数,但是不推荐手动指定。

  • --oom-kill-disable

    对某个容器关闭oom机制。

内存限制参数

  • -m or --memory

    容器可以使用的最大内存量,如果设置此选项,则允许的最小存值为4m。

  • --memory-swap

    容器可以使用的交换分区大小,必须要在设置了物理内存限制的前提才能设置交换分区的限制

  • --memory-swappiness

    设置容器使用交换分区的倾向性,值越高表示越倾向于使用swap分区,范围为0-100,0为能不用就不用,100为能用就用。

  • --kernel-memory

    容器可以使用的最大内核内存量,最小为4m,由于内核内存与用户空间内存隔离,因此无法与用户空间内存直接交换,因此内核内存不足的容器可能会阻塞宿主主机资源,这会对主机和其他容器或者其他服务进程产生影响,因此不要设置内核内存大小。

  • --memory-reservation

    允许指定小于--memory的软限制,当Docker检测到主机上的内存竞争或内存不足时会激活该限制,如果使用--memory-reservation,则必须将其设置为低于--memory才能使其优先。因为它是软限制,所以不能保证容器不超过限制。

  • --oom-kill-disable

    默认情况下,发生内存不足(OOM)时, kernel 会杀死容器内进程,但是可以使用--oom-kill-disable参数,可以禁止oom发生在指定的容器上,即仅在已设置-m/ - memory选项的容器上禁用OOM,如果-m参数未配置,产生OOM时,主机为了释放内存还会杀死系统进程。

swap限制

--memory-swap

只有在设置了-memory后才会有意义。使用Swap,可以让容器将超出限制部分的内存置换到磁盘上,WARNING:经常将内存交换到磁盘的应用程序会降低性能。

不同的--memory-swap设置会产生不同的效果:

  • --memory-swap

    值为正数,那么--memory--memory-swap都必须要设置,--memory-swap表示你能使用的内存和swap 分区大小的总和,例如:--memory=300m, --memory-swap=1g,那么该容器能够使用300m内存和700m swap,即--memory是实际物理内存大小值不变,而swap 的实际大小计算方式为(--memory-swap)-(--memory)=容器可用swap

  • --memory-swap

    如果设置为0,则忽略该设置,并将该值视为未设置,即未设置交换分区。

  • --memory-swap

    如果等于--memory的值,并且--memory设置为正整数,容器无权访问swap 即也没有设置交换分区。

  • --memory-swap

    如果设置为unset,如果宿主机开启了swap,则实际容器的swap值为2*(--memory),即两倍于物理内存大小,但是并不准确(在容器中使用free命令所看到的swap空间并不精确,毕竟每个容器都可以看到具体大小,但是宿主机的swap是有上限而且不是所有容器看到的累计大小)。

CPU限制

  • --cpus

    指定容器可以使用多少可用CPU 资源,例如,如果主机有两个CPU,并且设置了--cpus="1.5",那么该容器将保证最多可以访问1.5 个的CPU(如果是4核CPU,那么还可以是4核心上每核用一点,但是总计是1.5核心的CPU),这相当于设置--cpu-period="100000"(CPU调度周期)和--cpu-quota="150000"(CPU调度限制),--cpus主要在Docker 1.13和更高版本中使用,目的是替代--cpu-period--cpu-quota两个参数,从而使配置更简单,但是最大不能超出宿主机的CPU总核心数(在操作系统看到的CPU超线程后的数值)。

    示例

    docker run -it --rm--cpus 2 centos bash
    docker: Error response from daemon:Range of CPUs is from 0.01 to 1.00,as there are only 1 CPUs available.
    See 'docker run --help'. #分配给容器的CPU超出了宿主机CPU总数。
  • --cpu-period

    (CPU 调度周期)设置CPU的CFS调度程序周期,必须与--cpu-quota一起使用,默认周期为100微秒
    (1Second=1000Millisecond=1000000Microsecond)。

  • --cpu-quota

    在容器上添加CPU CFS配额,计算方式为cpu−quota/cpu−period的结果值,早期的docker(1.12及之前)使用此方式设置对容器的CPU限制值,新版本docker(1.13及以上版本)通常使用--cpus设置此值。

  • --cpuset-cpus

    用于指定容器运行的 CPU编号,也就是所谓的绑核。

  • --cpuset-mem

    设置使用哪个cpu的内存,仅对非统一内存访问(NUMA)架构有效。

  • --cpu-shares

    用于设置CFS中调度的相对最大比例权重,cpu-shares的值越高的容器,将会分得更多的时间片(宿主机多核CPU总数为100%,假如容器A为1024,容器B为2048,那么容器B将最大是容器A的可用CPU的两倍),默认的时间片1024,最大262144。

八、使用docker-compose部署wordpress;

  1. 安装docker

    方法同上

  2. 安装docker-compose

    # 安装pip
    apt install python3-pip -y
    # 安装docker-compose
    pip install docker-compose
  3. 下载mysq、WordPressl镜像

    docker pull mysql:5.7
    docker pull wordpress:latest
  4. 准备docker-compose文件

    mkdir -p /data/my_wordpress
    mkdir -pv /data/mysql
    mkdir -pv /data/wordpress
    cd /data/my_wordpress/
    vim docker-compose.yml

    yaml文件内容如下

    version: "3.9"
    services:
    db:
    image: mysql:5.7
    volumes:
    - /data/mysql:/var/lib/mysql
    restart: always
    environment:
    MYSQL_ROOT_PASSWORD: somewordpress
    MYSQL_DATABASE: wordpress
    MYSQL_USER: wordpress
    MYSQL_PASSWORD: wordpress
    wordpress:
    depends_on:
    - db
    image: wordpress:latest
    volumes:
    - /data/wordpress:/var/www/html
    ports:
    - "8000:80"
    restart: always
    environment:
    WORDPRESS_DB_HOST: db:3306
    WORDPRESS_DB_USER: wordpress
    WORDPRESS_DB_PASSWORD: wordpress
    WORDPRESS_DB_NAME: wordpress
    volumes:
    db_data: {}
    wordpress_data: {}
  5. 启动

    docker-compose up -d
  6. 查看容器

    [root@wordpress my_wordpress]#docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    ae534123ae76 wordpress:latest "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 0.0.0.0:8000->80/tcp, :::8000->80/tcp my_wordpress_wordpress_1
    51c6b37d5169 mysql:5.7 "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 3306/tcp, 33060/tcp my_wordpress_db_1

    查看宿主机生成数据文件

    [root@wordpress data]#tree /data -d -L 2
    /data
    ├── my_wordpress
    ├── mysql
    │ ├── mysql
    │ ├── performance_schema
    │ ├── sys
    │ └── wordpress
    └── wordpress
    ├── wp-admin
    ├── wp-content
    └── wp-includes
  7. 登录页面

    开始安装

    安装完成

  8. 进入首页

九、使用docker-compose实现nginx反向代理tomcat

架构

nginx
tomcat1
tomcat2
client

准备nginx文件

准备文件如下

[root@wordpress nginx]#tree /data/nginx/
/data/nginx/
├── conf
│ ├── conf.d
│ │ └── default.conf
│ ├── fastcgi_params
│ ├── mime.types
│ ├── nginx.conf
│ ├── scgi_params
│ └── uwsgi_params
└── html
└── index.html

查看nginx.conf内容

[root@wordpress nginx]#cat /data/nginx/conf/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
upstream tomcat-web {
server tomcat-app1:8080;
server tomcat-app2:8080;
}
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
server {
listen 80;
server_name _;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /app {
proxy_pass http://tomcat-web;
}
}
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
}

查看index.html内容

[root@wordpress nginx]#cat /data/nginx/html/index.html
test nginx

准备tomcat文件

准备文件如下

[root@wordpress data]#tree /data/tomcat/webapps/
/data/tomcat/webapps/
├── app1
│ └── index.html
└── app2
└── index.html

查看app1

[root@wordpress data]#cat /data/tomcat/webapps/app1/index.html
test-tomcat1

查看app2

[root@wordpress data]#cat /data/tomcat/webapps/app2/index.html
test-tomcat2

准备docker-compose文件

下载nginx、tomcat镜像

docker pull nginx:latest
docker pull tomcat:latest

编辑docker-compose.yaml文件

service-nginx-web:
image: nginx:latest
container_name: nginx-web
volumes:
- /data/nginx/html:/usr/share/nginx/html
- /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
- /data/nginx/conf/conf.d:/etc/nginx/conf.d
expose:
- 80
- 443
ports:
- "80:80"
- "443:443"
links:
- service-tomcat-app1
- service-tomcat-app2
service-tomcat-app1:
image: tomcat:latest
container_name: tomcat-app1
volumes:
- /data/tomcat/webapps/app1:/usr/local/tomcat/webapps/app
expose:
- 8080
ports:
- "8081:8080"
service-tomcat-app2:
image: tomcat:latest
container_name: tomcat-app2
volumes:
- /data/tomcat/webapps/app2:/usr/local/tomcat/webapps/app
expose:
- 8080
ports:
- "8082:8080"

启动容器

[root@wordpress data]#ls docker-compose.yaml
docker-compose.yaml
[root@wordpress data]#docker-compose up -d
Creating tomcat-app1 ... done
Creating tomcat-app2 ... done
Creating nginx-web ... done

查看容器

[root@wordpress data]#docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e56bdcffd589 nginx:latest "/docker-entrypoint.…" 41 minutes ago Up 41 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp nginx-web
9e30cd68f4f2 tomcat:latest "catalina.sh run" 41 minutes ago Up 41 minutes 0.0.0.0:8082->8080/tcp, :::8082->8080/tcp tomcat-app2
d000381f4d26 tomcat:latest "catalina.sh run" 41 minutes ago Up 41 minutes 0.0.0.0:8081->8080/tcp, :::8081->8080/tcp tomcat-app1

验证

  1. 访问nginx

  2. 访问app

    代理访问后端tomcat服务

    轮询访问后端tomcat服务

posted @   areke  阅读(523)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示