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
当运行此命令时,会发生以下情况(假设使用的是默认镜像仓库配置):
- 如果本地没有
ubuntu
镜像,Docker 会从配置的镜像仓库中提取它,就像docker pull ubuntu
手动运行一样。 - Docker 会创建一个新容器,就像
docker container create
手动运行命令一样。 - Docker 为容器分配一个读写文件系统,作为它的最后一层。这允许正在运行的容器在其本地文件系统中创建或修改文件和目录。
- Docker 创建了一个网络接口来将容器连接到默认网络,因为没有指定任何网络选项。这包括为容器分配 IP 地址。默认情况下,容器可以使用主机的网络连接连接到外部网络。
- Docker 启动容器并执行
/bin/bash
。因为容器以交互方式运行并附加到你的终端(-i
和-t
选项),你可以在输出记录到终端时使用键盘提供输入。 - 当输入exit停止
/bin/bash
命令时,容器会停止但不会被删除。你可以重新启动或删除它。
docke仓库
统一保存镜像而且是多个镜像版本的地方,叫做镜像仓库。
Image registry:docker 官方提供的使用仓库部署工具。
Docker hub: docker 官方的公共仓库,已经保存了大量的常见镜像,可以方便大家直接使用。
Harbor:vmware提供的自带Web界面、认证功能的镜像仓库。
当使用docker pull
或docker run
命令时,将从你配置的仓库中提取所需的镜像。当使用docker push
命令时,镜像会被推送到配置的仓库中。
二、docker安装及基础命令使用
ubuntu20安装docker
apt安装
-
设置仓库
- 安装依赖包
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 -
安装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版本
-
下载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 -
安装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
安装后验证
-
验证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" -
验证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 -
验证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 -
验证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资源限制) -
解决swap限制告警
[root@master ~]#vim /etc/default/grub # 对该行进行修改 GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 cgroup_enable=memory swapaccount=1" 修改完成后执行命令:
update-grub
重启服务器:
reboot
-
下载镜像并运行,验证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命令后就退出了
-
从镜像启动一个容器
直接进入到容器,并随机生成容器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
-
显示正在运行的容器
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 -
显示所有容器,包括运行以及关闭的容器
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 -
删除运行中的容器
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 -
随机映射端口
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随机端口
-
指定端口映射
方式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 -
查看容器已经映射的端口
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 -
自定容器名称
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 -
后台启动容器
示例
[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 ~]# -
创建并进入容器
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 -
单次运行
容器退出后自动删除
[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 -
传递运行命令
容器需要有一个前台运行的进程才能保持容器的运行,通过传递运行参数是一种方式,另外也可以在构建镜像的时候指定容器启动时运行的前台命令。
示例
[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 -
容器的启动和关闭
示例
# 容器关闭 [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 -
进入到正在运行的容器
-
使用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
-
-
查看容器内部的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 / # -
批量正常关闭正在运行的容器
示例
[root@master ~]#docker stop $(docker ps -a -q) a5f544c5365a 6c0af66c3052 -
批量强制关闭正在运行的容器
[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 -
批量删除已退出容器
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 -
批量删除所有容器
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 -
指定容器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 / # -
其他命令
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高可用方式主要有基于共享存储和基于镜像复制的两种方法

双主镜像复制高可用安装方法如下:
架构
安装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/
-
下载离线安装包
wget https://github.com/goharbor/harbor/releases/download/v2.4.3/harbor-offline-installer-v2.4.3.tgz
-
解压harbor
tar xvf harbor-offline-installer-v2.4.3.tgz -C /usr/local/src
-
配置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 -
执行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 -
若更新配置,可执行prepare
# 修改harbor.yml配置文件 [root@harbor1 harbor]# vim /usr/local/src/harbor/harbor.yml # 执行prepare [root@harbor1 harbor]#/usr/local/src/harbor/prepare -
查看本地镜像
[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 -
查看端口
[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 -
Web登录Harbor管理界面
用户名:admin
密码:Harbor12345
-
进入管理界面首页
镜像上传
-
配置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 -
登录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 -
上传镜像
- 导入镜像
# 先将前期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界面验证镜像上传成功
镜像下载
-
配置登录harbor仓库连接信息
# 添加harbor仓库信息 [root@harbor2 harbor]#cat /etc/docker/daemon.json {"insecure-registries":["10.0.0.22:80"]} # 重启docker [root@harbor2 harbor]#systemctl restart docker -
登录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 -
使用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 -
验证从镜像启动容器
[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 -
验证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;
-
安装docker
方法同上
-
安装docker-compose
# 安装pip apt install python3-pip -y # 安装docker-compose pip install docker-compose -
下载mysq、WordPressl镜像
docker pull mysql:5.7 docker pull wordpress:latest -
准备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: {} -
启动
docker-compose up -d -
查看容器
[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 -
登录页面
开始安装
安装完成
-
进入首页
九、使用docker-compose实现nginx反向代理tomcat
架构
准备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
验证
-
访问nginx
-
访问app
代理访问后端tomcat服务
轮询访问后端tomcat服务
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步