架构第四周

架构第四周

1 docker常用命令

1.1 docker 命令帮助

docker 命令是最常使用的docker 客户端命令,其后面可以加不同的参数以实现不同的功能

docker 命令格式

docker [OPTIONS] COMMAND

COMMAND分为
Management Commands #指定管理的资源对象类型,较新的命令用法,将命令按资源类型进行分类,方便使用
Commands             #对不同资源操作的命令不分类,使用容易产生混乱

docker 命令有很多子命令,可以用下面方法查看帮助

#docker 命令帮助
man docker
docker
docker --help

#docker 子命令帮助
man docker-COMMAND
docker COMMAND --help

1.2 查看 Docker 相关信息

1.2.1 查看 docker 版本

root@rocky8 ~]$ docker version
Client: Docker Engine - Community
 Version:           19.03.15
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        99e3ed8919
 Built:             Sat Jan 30 03:16:44 2021
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.15
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       99e3ed8919
  Built:            Sat Jan 30 03:15:19 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.15
  GitCommit:        5b842e528e99d4d4c1686467debf2bd4b88ecd86
 runc:
  Version:          1.1.4
  GitCommit:        v1.1.4-0-g5fd4c4d
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

1.2.2 查看 docker 详解信息

[root@ubuntu1804 ~]$ docker info
Client:
Debug Mode: false     #client 端是否开启 debug

Server:
 Containers: 2         #当前主机运行的容器总数
  Running: 0         #有几个容器是正在运行的
  Paused: 0         #有几个容器是暂停的
  Stopped: 2         #有几个容器是停止的
 Images: 4             #当前服务器的镜像数
 Server Version: 19.03.5     #服务端版本
 Storage Driver: overlay2     #正在使用的存储引擎
  Backing Filesystem: extfs #后端文件系统,即服务器的磁盘文件系统
  Supports d_type: true     #是否支持 d_type
  Native Overlay Diff: true #是否支持差异数据存储
 Logging Driver: json-file     #日志类型
 Cgroup Driver: cgroupfs     #Cgroups 类型
 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: runc                 #已安装的容器运行时
 Default Runtime: runc             #默认使用的容器运行时
 Init Binary: docker-init         #初始化容器的守护进程,即 pid 为 1 的进程
 containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339 #版本
 runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657 #runc 版本
 init version: fec3683             #init 版本
 Security Options:                 #安全选项
  apparmor                         #安全模块,https://docs.docker.com/engine/security/apparmor/
  seccomp                         #安全计算模块,即制容器操作,https://docs.docker.com/engine/security/seccomp/
   Profile: default             #默认的配置文件
 Kernel Version: 4.15.0-29-generic #宿主机内核版本
 Operating System: Ubuntu 18.04.1 LTS #宿主机操作系统
 OSType: linux                         #宿主机操作系统类型
 Architecture: x86_64                 #宿主机架构
 CPUs: 1                             #宿主机 CPU 数量
 Total Memory: 962MiB                 #宿主机总内存
 Name: ubuntu1804.wang.org             #宿主机 hostname
 ID: IZHJ:WPIN:BRMC:XQUI:VVVR:UVGK:NZBM:YQXT:JDWB:33RS:45V7:SQWJ #宿主机 ID
 Docker Root Dir: /var/lib/docker     #宿主机关于docker数据的保存目录
 Debug Mode: false                     #server 端是否开启 debug
 Registry: https://index.docker.io/v1/ #仓库路径
 Labels:
 Experimental: false                 #是否测试版
 Insecure Registries:
  127.0.0.0/8 :                     #非安全的镜像仓库
 Registry Mirrors:
  https://si7y70hh.mirror.aliyuncs.com/ #镜像仓库
 Live Restore Enabled: false #是否开启活动重启 (重启docker-daemon 不关闭容器 )

WARNING: No swap limit support     #系统警告信息 (没有开启 swap 资源限制 )

范例: 解决上述SWAP报警提示

官方文档: https://docs.docker.com/install/linux/linux-postinstall/#your-kernel-does-not-support-cgroup-swap-limit-capabilities

[root@ubuntu1804 ~]# vim /etc/default/grub
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=2
GRUB_DISTRIBUTOR=`lsb_ release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 swapaccount=1" #修改此行
[root@ubuntu1804 ~]# update-grub
[root@ubuntu1804 ~]# reboot

1.3 镜像管理命令

1.3.1 搜索镜像

官网: http://hub.docker.com

在官方的docker 仓库中搜索指定名称的docker镜像,也会有很多三方镜像。

执行docker search命令进行搜索

格式如下:

Usage: docker search [OPTIONS] TERM

Options:
  -f, --filter filter Filter output based on conditions provided
    --format string Pretty-print search using a Go template
    --limit int Max number of search results (default 25)
    --no-trunc Don't truncate output

说明:
OFFICIAL:     官方
AUTOMATED:     使用第三方docker服务来帮助编译镜像,可以在互联网上面直接拉取到镜像,减少了繁琐的编译过程

范例: 选择性的查找镜像

#搜索点赞100个以上的镜像
root@rocky8 ~]$ docker search --filter=stars=100 centos
NAME                DESCRIPTION                                 STARS               OFFICIAL            AUTOMATED
centos              DEPRECATED; The official build of CentOS.   7461                [OK]

1.3.2 下载镜像

从 docker 仓库将镜像下载到本地,命令格式如下:

docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Options:
  -a, --all-tags                  Download all tagged images in the repository
      --disable-content-trust     Skip image verification (default true)
      --platform                  string Set platform if server is multi-platform capable
  -q, --quiet                      Suppress verbose output

NAME: 是镜像名,一般的形式 仓库服务器:端口/项目名称/镜像名称
:TAG: 即版本号,如果不指定:TAG,则下载最新版镜像

镜像下载保存的路径: /var/lib/docker/overlay2/镜像ID

注意: 镜像下载完成后,会自动解压缩,比官网显示的可能会大很多

docker pull rockylinux:9-minimal
docker pull ubuntu:focal-20221130

1.3.3 查看本地镜像

docker images 可以查看下载至本地的镜像

格式:

docker images [OPTIONS] [REPOSITORY[:TAG]]
docker image ls [OPTIONS] [REPOSITORY[:TAG]]

#常用选项:
-q, --quiet      Only show numeric IDs
-a, --all        Show all images (default hides intermediate images)
    --digests      Show digests
    --no-trunc      Don't truncate output
-f, --filter      filter Filter output based on conditions provided
    --format      string Pretty-print images using a Go template

执行结果的显示信息说明:

REPOSITORY         #镜像所属的仓库名称
TAG             #镜像版本号(标识符),默认为latest
IMAGE ID         #镜像唯一ID标识,如果ID相同,说明是同一个镜像有多个名称
CREATED         #镜像在仓库中被创建时间
SIZE             #镜像的大小

Repository仓库

  • 由某特定的docker镜像的所有迭代版本组成的镜像仓库
  • 一个Registry中可以存在多个Repository
  • Repository可分为“顶层仓库”和“用户仓库”
  • Repository用户仓库名称一般格式为“用户名/仓库名”
  • 每个Repository仓库可以包含多个Tag(标签),每个标签对应一个镜像

1.3.4 镜像导出

利用docker save命令可以将从本地镜像导出为一个打包 tar文件,然后复制到其他服务器进行导入使用

格式:

docker save [OPTIONS] IMAGE [IMAGE...]

Options:
  -o, --output string   Write to a file, instead of STDOUT

#说明:
Docker save 使用IMAGE ID导出,在导入后的镜像没有REPOSITORY和TAG,显示为<none>

常见用法:

docker save -o /path/file.tar IMAGE1 IMAGE2 ...
docker save IMAGE1 IMAGE2 ... > /path/file.tar

范例: 导出指定镜像

[root@rocky8 ~]$ docker save alpine:latest -o alpine.tar
[root@rocky8 ~]$ scp alpine.tar 10.0.0.100:

范例: 导出所有镜像至不同的文件中

[root@rocky8 ~]$ docker images | awk 'NR!=1{print $1,$2}'|while read repo tag;do docker save $repo:$tag -o /opt/$repo-$tag.tar;done

[root@rocky8 ~]$ ll /opt/*.tar
-rw------- 1 root root   7347200 Jan 13 20:04 /opt/alpine-latest.tar
-rw------- 1 root root     24064 Jan 13 20:04 /opt/hello-world-latest.tar
-rw------- 1 root root 145905152 Jan 13 20:04 /opt/nginx-latest.tar
-rw------- 1 root root 121435136 Jan 13 20:04 /opt/rockylinux-9-minimal.tar
-rw------- 1 root root  75167744 Jan 13 20:04 /opt/ubuntu-focal-20221130.tar

范例:导出所有镜像到一个打包文件

#方法1: 使用image ID导出镜像,在导入后的镜像没有REPOSITORY和TAG,显示为<none>
docker save `docker images -qa` -o /opt/all.tar

#方法2:将所有镜像导入到一个文件中,此方法导入后可以看REPOSITORY和TAG
docker save $(docker images | awk 'NR!=1{print $1":"$2}') -o all-tags.tar

#方法3:将所有镜像导入到一个文件中,此方法导入后可以看REPOSITORY和TAG
docker save $(docker image ls --format "{{.Repository}}:{{.Tag}}") -o all-tags.tar

1.3.5 镜像导入

利用docker load命令可以将镜像导出的打包或压缩文件再导入

格式:

docker load [OPTIONS]

#选项
-i, --input string Read from tar archive file, instead of STDIN
-q, --quiet Suppress the load output

常见用法:

docker load -i /path/file.tar
docker load < /path/file.tar

范例: 镜像导入

[root@ubuntu2004 ~]$ docker load -i alpine.tar 
8e012198eea1: Loading layer  7.338MB/7.338MB
Loaded image: alpine:latest
[root@ubuntu2004 ~]$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
alpine       latest    042a816809aa   3 days ago   7.05MB

面试题: 将一台主机的所有镜像传到另一台主机

#方法1:将所有镜像导入到一个文件中,此方法导入后可以看REPOSITORY和TAG
[root@rocky8 ~]$ docker save $(docker images | awk 'NR!=1{print $1":"$2}') -o all-tags.tar
[root@ubuntu2004 ~]$ docker load < all-tags.tar
[root@ubuntu2004 ~]$ docker images 
REPOSITORY    TAG              IMAGE ID       CREATED         SIZE
alpine        latest           042a816809aa   3 days ago      7.05MB
rockylinux    9-minimal        c50e7a3e6f7f   3 weeks ago     118MB
ubuntu        focal-20221130   d5447fc01ae6   5 weeks ago     72.8MB
nginx         latest           605c77e624dd   12 months ago   141MB
hello-world   latest           feb5d9fea6a5   15 months ago   13.3kB

#方法2:将所有镜像导入到一个文件中,此方法导入后可以看REPOSITORY和TAG
[root@rocky8 ~]$ docker save $(docker image ls --format "{{.Repository}}:{{.Tag}}") -o all-tags.tar
[root@ubuntu2004 ~]$ docker load < all-tags.tar
[root@ubuntu2004 ~]$ docker images 
REPOSITORY    TAG              IMAGE ID       CREATED         SIZE
alpine        latest           042a816809aa   3 days ago      7.05MB
rockylinux    9-minimal        c50e7a3e6f7f   3 weeks ago     118MB
ubuntu        focal-20221130   d5447fc01ae6   5 weeks ago     72.8MB
nginx         latest           605c77e624dd   12 months ago   141MB
hello-world   latest           feb5d9fea6a5   15 months ago   13.3kB

1.3.6 删除镜像

docker rmi命令可以删除本地镜像

格式

docker rmi [OPTIONS] IMAGE [IMAGE...]
docker image rm [OPTIONS] IMAGE [IMAGE...]

#选项:
-f, --force Force removal of the image
    --no-prune Do not delete untagged parents

范例:

[root@ubuntu2004 ~]$ docker images 
REPOSITORY    TAG              IMAGE ID       CREATED         SIZE
alpine        latest           042a816809aa   3 days ago      7.05MB
rockylinux    9-minimal        c50e7a3e6f7f   3 weeks ago     118MB
ubuntu        focal-20221130   d5447fc01ae6   5 weeks ago     72.8MB
nginx         latest           605c77e624dd   12 months ago   141MB
hello-world   latest           feb5d9fea6a5   15 months ago   13.3kB

#删除镜像
[root@ubuntu2004 ~]$ docker rmi ubuntu:focal-20221130 
Untagged: ubuntu:focal-20221130
Deleted: sha256:d5447fc01ae62c20beffbfa50bc51b2797f9d7ebae031b8c2245b5be8ff1c75b
Deleted: sha256:0002c93bdb3704dd9e36ce5153ef637f84de253015f3ee330468dccdeacad60b

[root@ubuntu2004 ~]$ docker images 
REPOSITORY    TAG         IMAGE ID       CREATED         SIZE
alpine        latest      042a816809aa   3 days ago      7.05MB
rockylinux    9-minimal   c50e7a3e6f7f   3 weeks ago     118MB
nginx         latest      605c77e624dd   12 months ago   141MB
hello-world   latest      feb5d9fea6a5   15 months ago   13.3kB

强制删除正在使用的镜像,也会删除对应的容器

范例: 删除所有镜像

[root@ubuntu2004 ~]$ docker rmi $(docker images -q)

1.3.7 镜像打标签

docker tag 可以给镜像打标签,类似于起别名,但通常要遵守一定的命名规范,才可以上传到指定的仓库

格式

docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

#TARGET_IMAGE[:TAG]格式一般形式
仓库主机FQDN或IP[:端口]/项目名(或用户名)/image名字:版本

TAG默认为latest

范例

[root@rocky8 ~]$ docker tag rockylinux:9-minimal harbor.yanlinux.org:80/k8s/rockylinux:9
[root@rocky8 ~]$ docker images 
REPOSITORY                              TAG                 IMAGE ID            CREATED             SIZE
alpine                                  latest              042a816809aa        3 days ago          7.05MB
harbor.yanlinux.org:80/k8s/rockylinux   9                   c50e7a3e6f7f        3 weeks ago         118MB
rockylinux                              9-minimal           c50e7a3e6f7f        3 weeks ago         118MB
ubuntu                                  focal-20221130      d5447fc01ae6        5 weeks ago         72.8MB
nginx                                   latest              605c77e624dd        12 months ago       141MB
hello-world                             latest              feb5d9fea6a5        15 months ago       13.3kB

#然后就可以将镜像传到仓库中
[root@rocky8 ~]$ docker push harbor.yanlinux.org:80/k8s/rockylinux:9

总结: 企业使用镜像及常见操作: 搜索、下载、导出、导入、删除

命令总结:

docker search centos           #搜索镜像
docker pull alpine               #拉取镜像
docker images                  #查看本地所有镜像
docker save > /opt/centos.tar  #导出镜像
docker load -i /opt/centos.tar #导入本地镜像
docker rmi 镜像ID/镜像名称       #删除指定ID的镜像,此镜像对应容器正启动镜像不能被删除,除非将容器全部关闭

1.4 容器操作基础命令

容器相关命令

[root@rocky8 ~]$ docker container 

Usage:    docker container COMMAND

Manage containers

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  inspect     Display detailed information on one or more containers
  kill        Kill one or more running containers
  logs        Fetch the logs of a container
  ls          List containers
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  prune       Remove all stopped containers
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  run         Run a command in a new container
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

1.4.1 启动容器

docker run 可以启动容器,进入到容器,并随机生成容器ID和名称。docker run等价于docker pull + docker start

帮助: man docker run

命令格式:

docker run [选项] [镜像名] [shell命令] [参数]

#选项:
-i, --interactive         Keep STDIN open even if not attached,通常和-t一起使用
-t, --tty                 分配pseudo-TTY,通常和-i一起使用,注意对应的容器必须运行shell才支持进入
-d, --detach             Run container in background and print container ID,台后运行,默认前台
--name string             Assign a name to the container
--h, --hostname string     Container host name
--rm                     Automatically remove the container when it exits
-p, --publish list         Publish a container's port(s) to the host
-P, --publish-all         Publish all exposed ports to random ports
--dns list                 Set custom DNS servers
--entrypoint string     Overwrite the default ENTRYPOINT of the image
--restart policy
--privileged             Give extended privileges to container
-e, --env=[]             Set environment variables
--env-file=[]             Read in a line delimited file of environment variables

--restart 可以指定四种不同的policy

POLICY 说明
no 默认no,容器退出后不自动重启
on-failure[:max-retries] 仅当容器以非零退出状态退出时,才重新启动。(可选)限制 Docker 守护程序尝试的重新启动重试次数。
always 无论退出状态如何,始终重新启动容器。如果指定始终,Docker 守护程序将无限期地尝试重新启动容器。容器也将始终在守护程序启动时启动,无论容器的当前状态如何。利用此选项可以实现自动启动容器
unless-stopped 无论退出状态如何,始终重新启动容器,但如果容器之前已进入停止状态,则不要在守护程序启动时启动它。

注意: 容器启动后,如果容器内没有前台运行的进程,将自动退出停止

从容器内退出,并停止容器:

exit

从容器内退出,且容器不停止:

ctrl+p+q

范例:启动后台守护并指定运行容器的名字

[root@rocky8 ~]$ docker run -d --name web01 nginx
[root@rocky8 ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
b0b9221c09a9        nginx               "/docker-entrypoint.…"   5 seconds ago       Up 5 seconds        80/tcp              web01

范例: 一次性运行容器中命令

[root@rocky8 ~]$ docker run alpine cat /etc/issue
Welcome to Alpine Linux 3.17
Kernel \r on an \m (\l)

[root@rocky8 ~]$ docker run alpine du -sh /
7.0M    /

范例: 运行交互式容器并退出

退出两种方式:

  • exit 容器也停止
  • 按ctrl+p+q 容器不停止
[root@rocky8 ~]$ docker run -it alpine sh
/ # ls
bin    etc    lib    mnt    proc   run    srv    tmp    var
dev    home   media  opt    root   sbin   sys    usr
/ # cat /etc/issue 
Welcome to Alpine Linux 3.17
Kernel \r on an \m (\l)

#查看容器是在运行
[root@rocky8 ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
bad7e7c5ef39        alpine              "sh"                     7 seconds ago       Up 7 seconds                            angry_knuth

#现在在容器中执行退出
/ # exit

#查看容器是否运行
[root@rocky8 ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES

##另外一种退出容器的方法
##ctrl+p+q
/ # [22:13:43 root@rocky8 ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
2bae444f9796        alpine              "sh"                     51 seconds ago      Up 51 seconds                           nifty_davinci
#这种情况相当于临时从容器中出来,还可以利用以下命令进入进去
[root@rocky8 ~]$ docker exec -it 2bae444f9796 sh
/ # 

1.4.2 查看容器信息

1.4.2.1 显示当前存在容器

格式:

docker ps [OPTIONS]
docker container ls [OPTIONS]

选项:
-a, --all                 Show all containers (default shows just running)
-q, --quiet             Only display numeric IDs
-s, --size                 Display total file sizes
-f, --filter filter     Filter output based on conditions provided
-l, --latest             Show the latest created container (includes all states)
-n, --last int             Show n last created containers (includes all states)(default -1)

范例:

#显示正在运行的容器
[root@rocky8 ~]$ docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                            NAMES
d5bc9651615e        nginx                          "/docker-entrypoint.…"   3 minutes ago       Up 3 minutes        80/tcp                           web02
3d9a0cbfa238        docs/docker.github.io:latest   "/docker-entrypoint.…"   8 minutes ago       Up 8 minutes        80/tcp, 0.0.0.0:4000->4000/tcp   hardcore_curie

#显示全部容器,包括退出状态的容器
[root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS                     PORTS                            NAMES
d5bc9651615e        nginx                          "/docker-entrypoint.…"   3 minutes ago       Up 3 minutes               80/tcp                           web02
69cb07c29477        nginx                          "/docker-entrypoint.…"   4 minutes ago       Exited (0) 4 minutes ago                                    web01
3d9a0cbfa238        docs/docker.github.io:latest   "/docker-entrypoint.…"   9 minutes ago       Up 9 minutes               80/tcp, 0.0.0.0:4000->4000/tcp   hardcore_curie

#只显示容器ID
[root@rocky8 ~]$ docker ps -aq
d5bc9651615e
69cb07c29477
3d9a0cbfa238

#显示容器大小
[root@rocky8 ~]$ docker ps -s
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                            NAMES               SIZE
d5bc9651615e        nginx                          "/docker-entrypoint.…"   5 minutes ago       Up 5 minutes        80/tcp                           web02               1.09kB (virtual 141MB)
3d9a0cbfa238        docs/docker.github.io:latest   "/docker-entrypoint.…"   10 minutes ago      Up 10 minutes       80/tcp, 0.0.0.0:4000->4000/tcp   hardcore_curie      2B (virtual 1GB)

#显示最新创建的容器
root@rocky8 ~]$ docker ps -l
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
d5bc9651615e        nginx               "/docker-entrypoint.…"   5 minutes ago       Up 5 minutes        80/tcp              web02

范例:显示指定状态的容器

[root@rocky8 ~]$ docker ps -f "status=exited"
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
69cb07c29477        nginx               "/docker-entrypoint.…"   9 minutes ago       Exited (0) 9 minutes ago                       web01
1.4.2.2 查看容器内的进程
docker top CONTAINER [ps OPTIONS]

范例:

root@rocky8 ~]$ docker top web02 
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                2483                2468                0                   12:42               ?                   00:00:00            nginx: master process nginx -g daemon off;
101                 2534                2483                0                   12:42               ?                   00:00:00            nginx: worker process
101                 2535                2483                0                   12:42               ?                   00:00:00            nginx: worker process
1.4.2.3 查看容器资源使用情况
docker stats [OPTIONS] [CONTAINER...]

Display a live stream of container(s) resource usage statistics

Options:
-a, --all             Show all containers (default shows just running)
    --format         string Pretty-print images using a Go template
    --no-stream     Disable streaming stats and only pull the first result
    --no-trunc         Do not truncate output

范例:

root@rocky8 ~]$ docker stats web02 

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
d5bc9651615e        web02               0.00%               3.434MiB / 1.748GiB   0.19%               1.01kB / 0B         410kB / 25.6kB      3

范例:限制内存使用大小

[root@ubuntu1804 ~]#docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx128m" elasticsearch:7.6.2
[root@ubuntu1804 ~]#docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK PIDS
29282e91d773 elasti254.23310.5MiB / 1.924GiB 15.76% 766B / 0B 766kB /46kB 22
1.4.2.4 查看容器的详细信息

docker inspect 可以查看docker各种对象的详细信息,包括:镜像,容器,网络等

docker inspect [OPTIONS] NAME|ID [NAME|ID...]
Options:
-f, --format string     Format the output using the given Go template
-s, --size                 Display total file sizes if the type is container

范例:

root@rocky8 ~]$ docker inspect web02 
[
    {
        "Id": "d5bc9651615e461124d93651567548013db082229c7a0fbfe79ef211381c69e6",
        "Created": "2023-01-16T04:42:40.652945855Z",
        "Path": "/docker-entrypoint.sh",
        "Args": [
            "nginx",
            "-g",
            "daemon off;"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 2483,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2023-01-16T04:42:40.939507921Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85",
        "ResolvConfPath": "/var/lib/docker/containers/d5bc9651615e461124d93651567548013db082229c7a0fbfe79ef211381c69e6/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/d5bc9651615e461124d93651567548013db082229c7a0fbfe79ef211381c69e6/hostname",
        "HostsPath": "/var/lib/docker/containers/d5bc9651615e461124d93651567548013db082229c7a0fbfe79ef211381c69e6/hosts",
        "LogPath": "/var/lib/docker/containers/d5bc9651615e461124d93651567548013db082229c7a0fbfe79ef211381c69e6/d5bc9651615e461124d93651567548013db082229c7a0fbfe79ef211381c69e6-json.log",
        "Name": "/web02",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Capabilities": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/0581b9be2f2d1496b4b64de5b11514bbac17c9d4a8790a6d43a9c1b8e45c129a-init/diff:/var/lib/docker/overlay2/ac2a6764ef29d802f6d57c03311285e004854c1125392c571a54a0e51e7aa770/diff:/var/lib/docker/overlay2/00498af85ccf1634977fabaa1e8bc0347de69aa93c9a498932291ef6cc66ad2d/diff:/var/lib/docker/overlay2/e85525a30c0dc487cfe1bfed9931cc85994a3655f1194d5e357c9f52a29eb0c7/diff:/var/lib/docker/overlay2/616978347c6243ee5a035fb5dcd055a5bb72052fbc54e7da735babeef558d2aa/diff:/var/lib/docker/overlay2/6c5ffca8e721e566c9f03345b9bedc31db36328a5ec6a78c828d0b2ca4b21d89/diff:/var/lib/docker/overlay2/1dde0f444f04a43847d956a6cea24ce25fcc74c784086fe0f51ed17bb75e9ae8/diff",
                "MergedDir": "/var/lib/docker/overlay2/0581b9be2f2d1496b4b64de5b11514bbac17c9d4a8790a6d43a9c1b8e45c129a/merged",
                "UpperDir": "/var/lib/docker/overlay2/0581b9be2f2d1496b4b64de5b11514bbac17c9d4a8790a6d43a9c1b8e45c129a/diff",
                "WorkDir": "/var/lib/docker/overlay2/0581b9be2f2d1496b4b64de5b11514bbac17c9d4a8790a6d43a9c1b8e45c129a/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "d5bc9651615e",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.21.5",
                "NJS_VERSION=0.7.1",
                "PKG_RELEASE=1~bullseye"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "Image": "nginx",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
            },
            "StopSignal": "SIGQUIT"
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "83b75e77e1d7de17af47765c03f4c9e3aba0f93a615542e9e385fd97f29f961c",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "80/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/83b75e77e1d7",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "374829f09a774a1e0fc90815b29ff6964bb417bb788ef2e0e1264b1db9312e91",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.3",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:03",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "745daa224c76c2091d6852549ffaaa346bae3a7a2128186e5bbf40cbddf416a3",
                    "EndpointID": "374829f09a774a1e0fc90815b29ff6964bb417bb788ef2e0e1264b1db9312e91",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null
                }
            }
        }
    }
]

范例:选择性查看

root@rocky8 ~]$ docker inspect -f "{{.State.Status}}" web02 
running

root@rocky8 ~]$ docker inspect --format="{{.State.Status}}" web02
running

1.4.3 删除容器

docker rm 可以删除容器,即使容器正在运行当中,也可以被强制删除掉

格式

docker rm [OPTIONS] CONTAINER [CONTAINER...]
docker container rm [OPTIONS] CONTAINER [CONTAINER...]

#选项:
-f, --force     Force the removal of a running container (uses SIGKILL)
-v, --volumes     Remove the volumes associated with the container

#删除停止的容器
docker container prune [OPTIONS]
Options:
    --filter filter Provide filter values (e.g. 'until=<timestamp>')
  -f, --force Do not prompt for confirmation

范例:

root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS                      PORTS                            NAMES
ceb134349daf        alpine                         "/bin/sh"                50 seconds ago      Exited (0) 50 seconds ago                                    sharp_swanson
d5bc9651615e        nginx                          "/docker-entrypoint.…"   25 minutes ago      Up 25 minutes               80/tcp                           web02
69cb07c29477        nginx                          "/docker-entrypoint.…"   25 minutes ago      Exited (0) 25 minutes ago                                    web01
3d9a0cbfa238        docs/docker.github.io:latest   "/docker-entrypoint.…"   30 minutes ago      Up 30 minutes               80/tcp, 0.0.0.0:4000->4000/tcp   hardcore_curie

#删除web01容器
root@rocky8 ~]$ docker rm web01 
web01
[root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE                          COMMAND                  CREATED              STATUS                          PORTS                            NAMES
ceb134349daf        alpine                         "/bin/sh"                About a minute ago   Exited (0) About a minute ago                                    sharp_swanson
d5bc9651615e        nginx                          "/docker-entrypoint.…"   25 minutes ago       Up 25 minutes                   80/tcp                           web02
3d9a0cbfa238        docs/docker.github.io:latest   "/docker-entrypoint.…"   31 minutes ago       Up 31 minutes                   80/tcp, 0.0.0.0:4000->4000/tcp   hardcore_curie

范例: 删除指定状态的容器

[root@rocky8 ~]$ docker rm $(docker ps -qf status=exited)
ceb134349daf
[root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                            NAMES
d5bc9651615e        nginx                          "/docker-entrypoint.…"   27 minutes ago      Up 27 minutes       80/tcp                           web02
3d9a0cbfa238        docs/docker.github.io:latest   "/docker-entrypoint.…"   32 minutes ago      Up 32 minutes       80/tcp, 0.0.0.0:4000->4000/tcp   hardcore_curie

1.4.4 容器的启动和停止

格式

docker start|stop|restart|pause|unpause 容器ID

批量正常启动或关闭所有容器

docker start $(docker ps -a -q)
docker stop $(docker ps -a -q)

范例

[root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
e4af980c1bff        nginx               "/docker-entrypoint.…"   About a minute ago   Up About a minute   80/tcp              web01

#停止容器
[root@rocky8 ~]$ docker stop web01
[root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
e4af980c1bff        nginx               "/docker-entrypoint.…"   2 minutes ago       Exited (0) 4 seconds ago                       web01

#启动nginx容器
[root@rocky8 ~]$ docker start web01 
web01
[root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
e4af980c1bff        nginx               "/docker-entrypoint.…"   3 minutes ago       Up 2 seconds        80/tcp              web01

#重启nginx容器
[root@rocky8 ~]$ docker restart web01 

[10:05:45 root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
e4af980c1bff        nginx               "/docker-entrypoint.…"   4 minutes ago       Up 4 seconds        80/tcp              web01

范例: 启动并进入容器

root@rocky8 ~]$ docker run --name=rocky -it rockylinux:9-minimal bash
bash-5.1# ls
afs  dev  home    lib64        media  opt     root  sbin  sys  usr
bin  etc  lib    lost+found  mnt    proc  run   srv   tmp  var
bash-5.1# cat /etc/os-release 
NAME="Rocky Linux"
VERSION="9.1 (Blue Onyx)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.1"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Rocky Linux 9.1 (Blue Onyx)"
ANSI_COLOR="0;32"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:rocky:rocky:9::baseos"
HOME_URL="https://rockylinux.org/"
BUG_REPORT_URL="https://bugs.rockylinux.org/"
ROCKY_SUPPORT_PRODUCT="Rocky-Linux-9"
ROCKY_SUPPORT_PRODUCT_VERSION="9.1"
REDHAT_SUPPORT_PRODUCT="Rocky Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.1"
bash-5.1# exit
exit

#启动并进入rocky容器
[root@rocky8 ~]$ docker start -i rocky 
bash-5.1# cat etc/issue
\S
Kernel \r on an \m

bash-5.1#

范例: 暂停和恢复容器

#暂停web01容器
[root@rocky8 ~]$ docker pause web01
[root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS                     PORTS               NAMES
03357d030c20        rockylinux:9-minimal   "bash"                   6 minutes ago       Exited (0) 2 minutes ago                       rocky
e4af980c1bff        nginx                  "/docker-entrypoint.…"   11 minutes ago      Up 7 minutes (Paused)      80/tcp              web01 #状态中加上了paused标志

#恢复容器
[root@rocky8 ~]$ docker unpause web01 
web01
[root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS                     PORTS               NAMES
03357d030c20        rockylinux:9-minimal   "bash"                   7 minutes ago       Exited (0) 3 minutes ago                       rocky
e4af980c1bff        nginx                  "/docker-entrypoint.…"   12 minutes ago      Up 8 minutes               80/tcp              web01

1.4.5 给正在运行的容器发信号

docker kill 可以给容器发信号,默认号SIGKILL,即9信号

格式

docker kill [OPTIONS] CONTAINER [CONTAINER...]

#选项:
-s, --signal string   Signal to send to the container (default "KILL")

范例:

[root@rocky8 ~]$ docker kill web01 
web01
[root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS                      PORTS               NAMES
03357d030c20        rockylinux:9-minimal   "bash"                   9 minutes ago       Exited (0) 6 minutes ago                        rocky
e4af980c1bff        nginx                  "/docker-entrypoint.…"   15 minutes ago      Exited (137) 1 second ago                       web01

1.4.6 进入正在运行的容器

1.4.6.1 使用attach命令

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

格式:

docker attach [OPTIONS] CONTAINER
1.4.6.2 使用exec命令

在运行中的容器启动新进程,可以执行单次命令,以及进入容器

测试环境使用此方式,使用exit退出,但容器还在运行,此为推荐方式

格式:

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

常用选项:
-d, --detach         Detached mode: run command in the background
-e, --env list         Set environment variables
-i, --interactive     Keep STDIN open even if not attached
-t, --tty             Allocate a pseudo-TTY

#常见用法
docker exec -it 容器ID sh|bash

范例:

#执行一次性命令
[root@rocky8 ~]$ docker exec rocky cat /etc/redhat-release
Rocky Linux release 9.1 (Blue Onyx)

#进入容器,执行命令,exit退出容器不停止
[root@rocky8 ~]$ docker exec -it rocky bash
bash-5.1# cat /etc/redhat-release 
Rocky Linux release 9.1 (Blue Onyx)

1.4.7 暴露所有容器端口

容器启动后,默认处于预定义的NAT网络中,所以外部网络的主机无法直接访问容器中网络服务

docker run -P 可以将事先容器预定义的所有端口映射宿主机的网卡的随机端口,默认从32768开始

使用随机端口 时,当停止容器后再启动可能会导致端口发生变化

-P , --publish-all= true | false默认为false

#示例:
docker run -P docker.io/nginx #映射容器所有暴露端口至随机本地端口

范例

[root@rocky8 ~]$ docker run -d  --name web01 -P nginx
[root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
46b790b7393a        nginx               "/docker-entrypoint.…"   4 seconds ago       Up 4 seconds        0.0.0.0:32768->80/tcp   web01

docker port 可以查看容器的端口映射关系

格式

docker port CONTAINER [PRIVATE_PORT[/PROTO]]

范例

[root@rocky8 ~]$ docker port web01 
80/tcp -> 0.0.0.0:32768

端口映射的本质就是利用NAT技术实现的

1.4.8 指定端口映射

docker run -p 可以将容器的预定义的指定端口映射到宿主机的相应端口

注意: 多个容器映射到宿主机的端口不能冲突,但容器内使用的端口可以相同

方式1: 容器80端口映射宿主机本地随机端口

docker run -p 80 --name nginx-test-port1 nginx

方式2: 容器80端口映射到宿主机本地端口81

docker run -p 81:80 --name nginx-test-port2 nginx

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

docker run -p 10.0.0.100:82:80 --name nginx-test-port3 docker.io/nginx

方式4: 宿主机本地IP:宿主机本地随机端口:容器端口,默认从32768开始

docker run -p 10.0.0.100::80 --name nginx-test-port4 docker.io/nginx

方式5: 宿主机本机ip:宿主机本地端口:容器端口/协议,默认为tcp协议

docker run -p 10.0.0.100:83:80/udp --name nginx-test-port5 docker.io/nginx

方式6: 一次性映射多个端口+协议

docker run -p 8080:80/tcp -p 8443:443/tcp -p 53:53/udp --name nginx-test-port6 nginx

范例:

[root@rocky8 ~]$ docker run  -d -p 8080:80 --name web02 nginx
846ca3aa883687906cbc14884d2fc2c89d47884a1f3236c3f73bab628f18a121
[root@rocky8 ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
846ca3aa8836        nginx               "/docker-entrypoint.…"   5 seconds ago       Up 4 seconds        0.0.0.0:8080->80/tcp    web02
46b790b7393a        nginx               "/docker-entrypoint.…"   20 minutes ago      Up 20 minutes       0.0.0.0:32768->80/tcp   web01

[root@rocky8 ~]$ ss -ntl
State      Recv-Q     Send-Q           Local Address:Port            Peer Address:Port     Process     
LISTEN     0          128                    0.0.0.0:22                   0.0.0.0:*                    
LISTEN     0          128                       [::]:22                      [::]:*                    
LISTEN     0          128                          *:32768                      *:*                    
LISTEN     0          128                          *:8080                       *:*

实战案例: 修改已经创建的容器的端口映射关系

[root@ubuntu1804 ~]#docker run -d -p 80:80 --name nginx01 nginx
dc5d7c1029e582a3e05890fd18565367482232c151bba09ca27e195d39dbcc24
[root@ubuntu1804 ~]#docker port nginx01
80/tcp -> 0.0.0.0:80
[root@ubuntu1804 ~]#lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
docker-pr 2364 root 4u IPv6 35929 0t0 TCP *:http (LISTEN)
[root@ubuntu1804 ~]#ls
/var/lib/docker/containers/dc5d7c1029e582a3e05890fd18565367482232c151bba09ca27e195d39dbcc24/
checkpoints
hostconfig.json     mounts
config.v2.json
hostname             resolv.conf
dc5d7c1029e582a3e05890fd18565367482232c151bba09ca27e195d39dbcc24-json.log hosts
    resolv.conf.hash
[root@ubuntu1804 ~]#systemctl stop docker
[root@ubuntu1804 ~]#vim
/var/lib/docker/containers/dc5d7c1029e582a3e05890fd18565367482232c151bba09ca27e195d39dbcc24/hostconfig.json
"PortBindings":{"80/tcp":[{"HostIp":"","HostPort":"80"}]}
#PortBindings后80/tcp对应的是容器内部的80端口,HostPort对应的是映射到宿主机的端口80 修改此处为8000

[root@ubuntu1804 ~]#systemctl start docker
[root@ubuntu1804 ~]#docker start nginx01
[root@ubuntu1804 ~]#docker port nginx01
80/tcp -> 0.0.0.0:8000

范例:实现wordpress应用

#部署mysql
[root@rocky8 ~]$ docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=123456  --name mysql mysql:8.0.31-oracle

#下载wordpress
[root@rocky8 ~]$ docker run -d -p 80:80 --name wordpress wordpress:php7.4-apache

1.4.9 查看容器的日志

docker logs 可以查看容器中运行的进程在控制台输出的日志信息

格式

docker logs [OPTIONS] CONTAINER

选项:
--details Show extra details provided to logs
-f, --follow Follow log output
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
--tail string Number of lines to show from the end of the logs (default "all")
-t, --timestamps Show timestamps
--until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)

范例:

[root@rocky8 ~]$ docker logs wordpress 
WordPress not found in /var/www/html - copying now...
Complete! WordPress has been successfully copied to /var/www/html
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Tue Jan 17 04:10:22.767095 2023] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.51 (Debian) PHP/7.4.26 configured -- resuming normal operations
......

1.4.10 传递运行命令

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

容器里的PID为1的守护进程的实现方式

  • 服务类: 如: Nginx,Tomcat,Apache ,但服务不能停
  • 命令类: 如: tail -f /etc/hosts ,主要用于测试环境,注意: 不要tail -f <服务访问日志> 会产生不必要的磁盘IO

范例:

[root@rocky8 ~]$ docker run --name rocky rockylinux:9-minimal cat /etc/os-release
NAME="Rocky Linux"
VERSION="9.1 (Blue Onyx)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.1"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Rocky Linux 9.1 (Blue Onyx)"
ANSI_COLOR="0;32"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:rocky:rocky:9::baseos"
HOME_URL="https://rockylinux.org/"
BUG_REPORT_URL="https://bugs.rockylinux.org/"
ROCKY_SUPPORT_PRODUCT="Rocky-Linux-9"
ROCKY_SUPPORT_PRODUCT_VERSION="9.1"
REDHAT_SUPPORT_PRODUCT="Rocky Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.1"

1.4.11 容器内和宿主机之间复制文件

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
Options:
  -a, --archive         Archive mode (copy all uid/gid information)
  -L, --follow-link     Always follow symbol link in SRC_PATH

范例:

[root@rocky8 ~]$ docker run -itd --rm alpine

#将宿主机文件复制到容器中
[root@rocky8 ~]$ docker cp /etc/hosts 2b91caf6ba44:/
[root@rocky8 ~]$ docker exec -it 2b91caf6ba44 sh
/ # cat hosts 
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

#将容器内的文件复制到宿主机
[root@rocky8 ~]$ docker cp 2b91caf6ba44:/bin/busybox /usr/local/bin/
[root@rocky8 ~]$ ls /usr/local/bin/
busybox

1.5 Docker镜像制作和管理命令

Docker的镜像制作分为手动制作(基于容器)和自动制作(基于DockerFile),企业通常都是基于Dockerfile制作镜像

docker commit #通过修改现有容器,将之手动构建为镜像
docker build  #通过Dockerfile文件,批量构建为镜像

1.5.1 docker commit 手动构建镜像

1.5.1.1 基于容器手动制作镜像步骤

docker commit 格式

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
#选项
-a, --author     string Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
-c, --change     list Apply Dockerfile instruction to the created image
-m, --message     string Commit message
-p, --pause     Pause container during commit (default true)

#说明:
制作镜像和CONTAINER状态无关,停止状态也可以制作镜像
如果没有指定[REPOSITORY[:TAG]],REPOSITORY和TAG都为<none>
提交的时候标记TAG号: 生产当中常用,后期可以根据TAG标记创建不同版本的镜像以及创建不同版本的容器

基于容器手动制作镜像步骤具体如下:

  • 下载一个系统的官方基础镜像,如: CentOS 或 Ubuntu
  • 基于基础镜像启动一个容器,并进入到容器
  • 在容器里面做配置操作
    • 安装基础命令
    • 配置运行环境
    • 安装服务和配置服务
    • 放业务程序代码
  • 提交为一个新镜像 docker commit
  • 基于自己的镜像创建容器并测试访问
1.5.1.2 实战案例: 基于 rocky8.5 制作 自我需求的rocky 镜像
#运行容器
[root@rocky8 ~]$ docker run  -it  rockylinux:9-minimal sh

#安装基础包
[root@c85d96e2158a ~]# yum -y install bash-completion psmisc tree vim lsof iproute git net-tools

#创建组和用户
[root@c85d96e2158a ~]# groupadd -g 88 www
[root@c85d96e2158a ~]# useradd -g www -u 88 -r -s /sbin/nologin -M -d /home/www www
[root@c85d96e2158a ~]# id www
uid=88(www) gid=88(www) groups=88(www)

#清楚yum缓存,减少制作的镜像的大小
[root@rocky8 ~]$ docker commit rocky9 rockylinux:v8.5-2023-01-17
sha256:1af952b962d9501a4249c69132baa733e384933c6db76d0794a40998c38af588
[root@rocky8 ~]$ docker images 
REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
rockylinux                            v8.5-2023-01-17     1af952b962d9        3 seconds ago       327MB

1.5.2 利用 DockerFile 文件执行 docker build 自动构建镜像

1.5.2.1 Dockerfile 文件格式

Dockerfile 是一个有特定语法格式的文本文件

dockerfile 官方说明: https://docs.docker.com/engine/reference/builder/

帮助: man 5 dockerfile

Dockerfile 文件说明

  • 每一行以Dockerfile的指令开头,指令不区分大小写,但是惯例使用大写
  • 使用 #开始作为注释
  • 一行只支持一条指令,每条指令可以携带多个参数
  • 指令按文件的顺序从上至下进行执行
  • 每个指令的执行会生成一个新的镜像层,为了减少分层和镜像大小,尽可能将多条指令合并成一条指令
  • 制作镜像一般可能需要反复多次,每次执行dockfile都按顺序执行,从头开始,已经执行过的指令已经缓存,不需要再执行,如果后续有一行新的指令没执行过,其往后的指令将会重新执行,所以为加速镜像制作,将最常变化的内容放下dockerfile的文件的后面
1.5.2.2 Dockerfile 相关指令

dockerfile 文件中的常见指令:

ADD
COPY
ENV
EXPOSE
FROM
LABEL
STOPSIGNAL
USER
VOLUME
WORKDIR

2 基于alpine基础镜像构建常见的系统服务,任选三个完成[nginx/jdk/apache/haproxy/tomcat等等]。

2.1 制作alpine自定义镜像

Alpine使用的c库使用mini版的musl libc与其他Linux发行版使用的gnu libc不一样。虽说号称兼容,但也只是部分兼容了。Alpine官方给出了Alpine的三大特征 Small、Simple、Secure,但其实我们知道一个jdk就已经不小了,强行安装只会违背Alpine的设计初衷,最后其实与其他操作系统差不多了。所以对于java程序来说使用CentOS等操作系统会更好一下。

强行利用alpinean使用jdk就要安装glibc

#下载alpine镜像
[root@rocky8 alpine]$ docker pull alpine:3.17.2

#准备相关文件
[root@rocky8 alpine]$ pwd
/data/dockerfile/system/alpine
[root@rocky8 alpine]$ cat > repositories <<EOF
http://mirrors.aliyun.com/alpine/v3.11/main
http://mirrors.aliyun.com/alpine/v3.11/community
EOF

#制作Dockerfile文件
[root@rocky8 alpine]$ vi Dockerfile
[root@rocky8 alpine]$ cat Dockerfile 
FROM alpine:3.17.2
LABEL author=yanlinux
COPY repositories /etc/apk/repositories
RUN apk update && apk --no-cache add iotop gcc bash libgcc libc-dev libcurl libc-utils pcre-dev zlib-dev libnfs make pcre pcre2 zip unzip net-tools pstree wget libevent libevent-dev iproute2 && \
    wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
    wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-2.30-r0.apk && \
    apk add --force glibc-2.30-r0.apk && \
    rm -rf *.apk && \
    rm -rf /var/cache/apk/*

#构建镜像
[root@rocky8 alpine]$ docker build -t alpine-base:3.17.2 .
[root@rocky8 alpine]$ docker images alpine-base
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine-base         3.17.2              28edf4ec236f        55 seconds ago      189MB

2.2 基于自定义alpine镜像制作nginx镜像

#准备相关文件
[root@rocky8 ~]$ mkdir /data/dockerfile/web/nginx/alpine-3.17.2
[root@rocky8 ~]$ cd /data/dockerfile/web/nginx/alpine-3.17.2
[root@rocky8 alpine-3.17.2]$ wget http://nginx.org/download/nginx-1.22.1.tar.gz
[root@rocky8 alpine-3.17.2]$ cat index.html 
<h1>welcome to nginx docker website!</h1>

[root@rocky8 alpine-3.17.2]$ cat nginx.conf 
user  www;
worker_processes  auto;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
......

#编写Dockerfile文件
[root@rocky8 alpine-3.17.2]$ cat Dockerfile 
FROM alpine-base:3.17.2
LABEL author=yanlinux
ENV NGINX_VERSION=1.22.1
ADD nginx-${NGINX_VERSION}.tar.gz /usr/local
RUN addgroup -g 88 www && \
    adduser -G www -u 88  -s /sbin/nologin -S -D www && \
    cd /usr/local/nginx-${NGINX_VERSION} && \
    ./configure --prefix=/apps/nginx && \
    make && make install && \
    ls -s /apps/nginx/sbin/nginx /usr/bin/ 
COPY nginx.conf /apps/nginx/conf
COPY index.html /data/html/index.html
VOLUME ["/data/html/"]
EXPOSE 80
CMD /apps/nginx/sbin/nginx -g "daemon off;"

#目录下所有文件
[root@rocky8 alpine-3.17.2]$ ls
Dockerfile  index.html  nginx-1.22.1.tar.gz  nginx.conf

#构建镜像
[root@rocky8 alpine-3.17.2]$ docker build -t nginx-alpine:1.22.1 .
[root@rocky8 alpine-3.17.2]$ docker images nginx-alpine
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx-alpine        1.22.1              04608cd5fcbf        3 minutes ago       213MB

#运行容器测试镜像业务正常
[root@rocky8 alpine-3.17.2]$ docker run -d --name nginx01 -p 80:80 nginx-alpine:1.22.1
[root@rocky8 alpine-3.17.2]$ curl 127.0.0.1
<h1>welcome to nginx docker website!</h1>

2.3 基于自定义alpine镜像制作jdk镜像

#从alpine容器中拷贝一份/etc/profile文件
[root@rocky8 jdk]$ docker run -it --rm alpine-base:3.17.2 sh
[root@rocky8 jdk]$ docker ps
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS               NAMES
ae3595b2d8cf        alpine-base:3.17.2   "sh"                3 minutes ago       Up 3 minutes                            ecstatic_nobel
[root@rocky8 jdk]$ docker cp ae3595b2d8cf:/etc/profile /data/dockerfile/web/jdk/

#修改profile文件,加下面四行相关变量
[root@rocky8 jdk]$ vi profile
......
export JAVA_HOME=/usr/local/jdk
export TOMCAT_HOME=/apps/tomcat
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$TOMCAT_HOME/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar

#下载jdk文件到目录下
[root@rocky8 jdk]$ tree /data/dockerfile/web/jdk/
/data/dockerfile/web/jdk/
├── Dockerfile
├── jdk-8u202-linux-x64.tar.gz
└── profile

0 directories, 3 files

#制作Dockerfile文件
[root@rocky8 jdk]$ vi Dockerfile
FROM alpine-base:3.17.2
LABEL maintainer="yanlinux"
ENV JDK_VERSION=8u202
ENV JAVA_HOME="/usr/local/jdk"
ENV JRE_HOME="${JAVA_HOME}/jre"
ENV CLASSPATH="$JAVA_HOME/lib/:$JRE_HOME/lib/"
ENV PATH="$PATH:$JAVA_HOME/bin"
ADD jdk-${JDK_VERSION}-linux-x64.tar.gz /usr/local/src/
ADD profile /etc/profile
RUN ln -s /usr/local/src/jdk1.8.0_202 /usr/local/jdk && \
    . /etc/profile

#构建镜像
[root@rocky8 jdk]$ docker build -t alpine-jdk:8u202 .
[root@rocky8 jdk]$ docker images alpine-jdk
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine-jdk          8u202               af9682420c5c        29 seconds ago      591MB

#测试镜像
[root@rocky8 jdk]$ docker run -it --rm --name jdk alpine-jdk:8u202 sh
/ # java  -version
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)

2.4 JDK镜像构建tomcat 8 Base镜像

#准备tomcat包
[root@rocky8 tomcat]$ pwd
/data/dockerfile/web/tomcat
[root@rocky8 tomcat]$ mkdir tomcat-base-8.5.85
[root@rocky8 tomcat]$ cd tomcat-base-8.5.85/
[root@rocky8 tomcat-base-8.5.85]$ pwd
/data/dockfile/web/tomcat/tomcat-base-8.5.85
[root@rocky8 tomcat-base-8.5.85]$ wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.85/bin/apache-tomcat-8.5.85.tar.gz

#编辑Dockerfie文件
[root@rocky8 tomcat-base-8.5.85]$ cat Dockerfile 
FROM alpine-jdk:8u202
ENV TZ "Asia/Shanghai"
ENV LANG en_US.UTF-8
ENV TERM xterm
ENV TOMCAT_MAJOR_VERSION 8
ENV TOMCAT_MINOR_VERSION 8.5.85
ENV CATALINA_HOME /apps/tomcat
ENV APP_DIR ${CATALINA_HOME}/webapps
RUN mkdir /apps
ADD apache-tomcat-8.5.85.tar.gz /apps
RUN ln -s /apps/apache-tomcat-8.5.85 /apps/tomcat

#构建镜像
[root@rocky8 tomcat-base-8.5.85]$ docker build -t tomcat-base:v8.5.85 .
[root@rocky8 tomcat-base-8.5.85]$ docker images tomcat-base
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
tomcat-base         v8.5.85             f5a9ab5c83ab        26 seconds ago      615MB

#验证镜像
[root@rocky8 tomcat-base-8.5.85]$  docker run -it --rm -p 8080:8080 tomcat-base:v8.5.85 bash
bash-5.0# /apps/tomcat/bin/catalina.sh start
Using CATALINA_BASE:   /apps/tomcat
Using CATALINA_HOME:   /apps/tomcat
Using CATALINA_TMPDIR: /apps/tomcat/temp
Using JRE_HOME:        /usr/local/jdk/jre
Using CLASSPATH:       /apps/tomcat/bin/bootstrap.jar:/apps/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
bash-5.0# ps auxf
PID   USER     TIME  COMMAND
    1 root      0:00 bash
   11 root      0:01 /usr/local/jdk/jre/bin/java -Djava.util.logging.config.file=/apps/tomcat/conf/log
   39 root      0:00 ps auxf
bash-5.0# netstat -ntl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:8005          0.0.0.0:*               LISTEN

2.5 基于自定义alpine镜像制作haproxy镜像

#准备相关文件
[root@rocky8 web]$ pwd
/data/dockfile/web
[root@rocky8 web]$ mkdir haproxy/2.1.2-alpine/files -p
[root@rocky8 web]$ cd haproxy/2.1.2-alpine/files
[root@rocky8 files]$ wget http://www.haproxy.org/download/2.1/src/haproxy-2.1.2.tar.gz

#准备install.sh脚本
[root@rocky8 files]$ cat install.sh 
#!/bin/bash
apk update
adduser -S -H -s /sbin/nologin haproxy
addgroup haproxy
apk add --no-cache -U make gcc pcre-dev bzip2-dev openssl-dev elogind-dev libc-dev dahdi-tools dahdi-tools-dev libexecinfo libexecinfo-dev ncurses-dev zlib-dev zlib
cd /tmp/
tar xf haproxy-${version}.tar.gz 
cd haproxy-$version 
make clean 
make -j $(nproc) \
TARGET=linux-musl  \
USE_OPENSSL=1  \
USE_ZLIB=1  \
USE_PCRE=1 && \
make install PREFIX=/usr/local/haproxy && \
echo 'net.ipv4.ip_nonlocal_bind = 1' >>  /etc/sysctl.conf 
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf 
mkdir /usr/local/haproxy/conf
apk del  gcc  make
rm -rf   /var/cache/* /tmp/*

#准备haproxy启动脚本
[root@rocky8 files]$ cd ../
[root@rocky8 2.1.2-alpine]$ cat entrypoint.sh 
#!/bin/bash
cat > /usr/local/haproxy/conf/haproxy.cfg << EOF
#--------------全局配置----------------
global
    log 127.0.0.1 local0  info
    #log loghost local0 info
    maxconn 20480
#chroot /usr/local/haproxy
    pidfile /var/run/haproxy.pid
    #maxconn 4000
    user haproxy
    group haproxy
    daemon
#---------------------------------------------------------------------
#common defaults that all the 'listen' and 'backend' sections will
#use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode http
    log global
    option dontlognull
    option httpclose
    option httplog
    #option forwardfor
    option redispatch
    balance roundrobin
    timeout connect 10s
    timeout client 10s
    timeout server 10s
    timeout check 10s
    maxconn 60000
    retries 3
#--------------统计页面配置------------------
listen admin_stats
    bind 0.0.0.0:8189
    stats enable
    mode http
    log global
    stats uri /haproxy_stats
    stats realm Haproxy\ Statistics
    stats auth admin:admin
    #stats hide-version
    stats admin if TRUE
    stats refresh 30s
#---------------web设置-----------------------
listen webcluster
    bind 0.0.0.0:80
    mode http
    #option httpchk GET /index.html
    log global
    maxconn 3000
    balance roundrobin
    cookie SESSION_COOKIE insert indirect nocache
EOF
count=1
for rs_ip in $(cat /tmp/RSs.txt);do
    cat >> /usr/local/haproxy/conf/haproxy.cfg << EOF
    server web$count $rs_ip:80 check inter 2000 fall 5
EOF
    let count++
done
/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg -db


#制作Dockerfile文件
[root@rocky8 2.1.2-alpine]$ cat Dockerfile 
FROM alpine-base:3.17.2
LABEL MAINTAINER='yanlinux.org@3.com'
ENV PATH /usr/local/haproxy/sbin:$PATH
ENV version 2.1.2
COPY files /tmp/
COPY entrypoint.sh /
RUN /tmp/install.sh
EXPOSE 80 8189
WORKDIR /usr/local/haproxy
ENTRYPOINT  ["/entrypoint.sh"]

#构建镜像
[root@rocky8 2.1.2-alpine]$ docker build -t haproxy-alpine:2.1.2 .
[root@rocky8 2.1.2-alpine]$ docker images haproxy-alpine
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
haproxy-alpine      2.1.2               9eeb5cb28dbe        3 minutes ago       226MB

3 将上面构建的镜像放在阿里云仓库。

3.1 注册和登录阿里云仓库

用浏览器访问http://cr.console.aliyun.com,输入注册的用户信息登录网站

3.2 设置仓库专用管理密码

3.3 创建仓库

此步可不事先执行,docker push 时可以自动创建私有仓库

3.4 上传镜像前先登录阿里云

#用前面设置的专用仓库管理密码登录
[root@rocky8 ~]$ docker login --username=焱黎123 registry.cn-hangzhou.aliyuncs.com
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.5 给上传的镜像打标签

[root@rocky8 ~]$ docker tag alpine-base:3.17.2 registry.cn-hangzhou.aliyuncs.com/yanlinux/alpine-base:3.17.2
[root@rocky8 ~]$ docker tag nginx-alpine:1.22.1 registry.cn-hangzhou.aliyuncs.com/yanlinux/nginx-alpine:1.22.1
[root@rocky8 ~]$ docker tag alpine-jdk:8u202 registry.cn-hangzhou.aliyuncs.com/yanlinux/alpine-jdk:8u202
[root@rocky8 ~]$ docker tag tomcat-base:v8.5.85 registry.cn-hangzhou.aliyuncs.com/yanlinux/tomcat-base:v8.5.85
[root@rocky8 ~]$ docker tag haproxy-alpine:2.1.2 registry.cn-hangzhou.aliyuncs.com/yanlinux/haproxy-alpine:2.1.2

3.6 上传镜像

[root@rocky8 ~]$ docker push registry.cn-hangzhou.aliyuncs.com/yanlinux/alpine-base:3.17.2
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/yanlinux/alpine-base]
87c8bbf9e2e8: Pushed 
0ba47f277eb9: Pushed 
7cd52847ad77: Pushed 
3.17.2: digest: sha256:d2aaa9d3e26da43e5b83d02b92aab403f33e9d4c9a3e9171a14ef314692e4a7a size: 947
[root@rocky8 ~]$ docker push registry.cn-hangzhou.aliyuncs.com/yanlinux/nginx-alpine:1.22.1
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/yanlinux/nginx-alpine]
fa80f3c76ef6: Pushed 
01c65a043850: Pushed 
adbe8696b1b4: Pushed 
1e356a844716: Pushed 
ebb41e59056a: Pushed 
0ba47f277eb9: Mounted from yanlinux/alpine-base 
7cd52847ad77: Mounted from yanlinux/alpine-base 
1.22.1: digest: sha256:104304b5133de8acd1978485c2d980748dab7314d267d29b4278f22573010058 size: 1784
[root@rocky8 ~]$ docker push registry.cn-hangzhou.aliyuncs.com/yanlinux/alpine-jdk:8u202
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/yanlinux/alpine-jdk]
d88c104af48e: Pushed 
4236564ab151: Pushed 
31af46d91eef: Pushed 
87c8bbf9e2e8: Mounted from yanlinux/alpine-base 
0ba47f277eb9: Mounted from yanlinux/nginx-alpine 
7cd52847ad77: Mounted from yanlinux/nginx-alpine 
8u202: digest: sha256:6a93df44d46e757dda66a6c2f8ea28c11d3954d3c714392b608c40f45b2e2413 size: 1574
[root@rocky8 ~]$ docker push registry.cn-hangzhou.aliyuncs.com/yanlinux/tomcat-base:v8.5.85
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/yanlinux/tomcat-base]
6d1a20593ad3: Pushed 
8d7f5b279153: Pushed 
0abb32fe3733: Pushed 
d88c104af48e: Mounted from yanlinux/alpine-jdk 
4236564ab151: Mounted from yanlinux/alpine-jdk 
31af46d91eef: Mounted from yanlinux/alpine-jdk 
87c8bbf9e2e8: Mounted from yanlinux/alpine-jdk 
0ba47f277eb9: Mounted from yanlinux/alpine-jdk 
7cd52847ad77: Mounted from yanlinux/alpine-jdk 
v8.5.85: digest: sha256:a19bb6ff4a407cbd9881a27b8ca412b6bd45d5fd0b8bff35e6a6d759813fb273 size: 2200
[root@rocky8 ~]$ docker push registry.cn-hangzhou.aliyuncs.com/yanlinux/haproxy-alpine:2.1.2
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/yanlinux/haproxy-alpine]
406ce5ba5219: Pushed 
3ecff3848c3e: Pushed 
89180f31278f: Pushed 
87c8bbf9e2e8: Mounted from yanlinux/tomcat-base 
0ba47f277eb9: Mounted from yanlinux/tomcat-base 
7cd52847ad77: Mounted from yanlinux/tomcat-base 
2.1.2: digest: sha256:bbf660062436f982e820d2daacb8fcd1d83ecc06115e178bfe094b8c4f513066 size: 1576

4 将构建的镜像,放在自建的harbor中,并且单独可以提供相应的服务

4.1 搭建harbor服务器

[root@rocky8 ~]$ cat /data/scripts/install_harbor.sh 
#!/bin/bash

DOCKER_VERSION="20.10.10"
UBUNTU_DOCKER_VERSION="5:${DOCKER_VERSION}~3-0~${ID}-${UBUNTU_CODENAME}"
DOCKER_COMPOSE_VERSION="2.16.0"
DOCKER_COMPOSE_FILE=docker-compose-Linux-x86_64
HARBOR_VERSION="2.5.6"
HARBOR_BASE="/usr/local/"
HARBOR_NAME=harbor.yanlinux.org
HARBOR_IP=`hostname -I|awk '{print $1}'`
HARBOR_ADMIN_PASSWORD=123456

COLOR_SUCCESS="echo -e \\033[1;32m"
COLOR_FAILURE="echo -e \\033[1;31m"
END="\033[m"

. /etc/os-release

color () {
    RES_COL=60
    MOVE_TO_COL="echo -en \\033[${RES_COL}G"
    SETCOLOR_SUCCESS="echo -en \\033[1;32m"
    SETCOLOR_FAILURE="echo -en \\033[1;31m"
    SETCOLOR_WARNING="echo -en \\033[1;33m"
    SETCOLOR_NORMAL="echo -en \E[0m"
    echo -n "$1" && $MOVE_TO_COL
    echo -n "["
    if [ $2 = "success" -o $2 = "0" ] ;then
        ${SETCOLOR_SUCCESS}
        echo -n $"  OK  "
    elif [ $2 = "failure" -o $2 = "1"  ] ;then
        ${SETCOLOR_FAILURE}
        echo -n $"FAILED"
    else
        ${SETCOLOR_WARNING}
        echo -n $"WARNING"
    fi
    ${SETCOLOR_NORMAL}
    echo -n "]"
    echo
}

install_docker() {
    if [ $ID = "centos" -o $ID = "rocky" ];then
        if [ $VERSION_ID = "7" ];then
            cat >  /etc/yum.repos.d/docker.repo  <<EOF
[docker]
name=docker
gpgcheck=0
#baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/
EOF
        else     
            cat >  /etc/yum.repos.d/docker.repo  <<EOF
[docker]
name=docker
gpgcheck=0
#baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/8/x86_64/stable/
EOF
        fi
        yum clean all
        yum makecache
        ${COLOR_FAILURE} "Docker有以下版本"${END}
        yum list docker-ce --showduplicates
        ${COLOR_FAILURE}"5秒后即将安装: docker-"${DOCKER_VERSION}" 版本....."${END}
        sleep 5
        yum -y install docker-ce-${DOCKER_VERSION} docker-ce-cli-${DOCKER_VERSION} || { color "Base,Extras的yum源失败,请检查yum源配置" 1;exit; }
    else
        dpkg -s docker-ce &> /dev/null && $COLOR"Docker已安装,退出" 1 && exit
        apt update || { color "更新包索引失败" 1 ; exit 1; }
        apt  -y install apt-transport-https ca-certificates curl software-properties-common || \
            { color "安装相关包失败" 1 ; exit 2;  }
        curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
        add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
        apt update
        ${COLOR_FAILURE} "Docker有以下版本"${END}
        apt-cache madison docker-ce
        ${COLOR_FAILURE}"5秒后即将安装: docker-"${UBUNTU_DOCKER_VERSION}" 版本....."${END}
        ${COLOR_FAILURE}"如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行"${END}
        sleep 5
        apt -y  install docker-ce=${UBUNTU_DOCKER_VERSION} docker-ce-cli=${UBUNTU_DOCKER_VERSION}
    fi

    if [ $? -eq 0 ];then
        color "安装软件包成功"  0
    else
        color "安装软件包失败,请检查网络配置" 1
        exit
    fi
    mkdir -p /etc/docker
    tee /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://5lwrg1ye.mirror.aliyuncs.com"],
  "insecure-registries":["harbor.yanlinux.org"]
}
EOF
    systemctl daemon-reload
    systemctl enable docker
    systemctl restart docker
    docker version && color "Docker 安装成功" 0 ||  color "Docker 安装失败" 1

    echo 'alias rmi="docker images -qa|xargs docker rmi -f"' >> ~/.bashrc
    echo 'alias rmc="docker ps -qa|xargs docker rm -f"' >> ~/.bashrc
    echo 'alias dps="docker ps -a"' >> ~/.bashrc
    echo 'alias dim="docker images"' >> ~/.bashrc
}

install_docker_compose() {
    ${COLOR_SUCCESS}"开始安装 Docker compose....."${END}
    sleep 5
    if [ ! -e ${DOCKER_COMPOSE_FILE} ];then
        curl -L https://get.daocloud.io/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose
    else
        mv ${DOCKER_COMPOSE_FILE} /usr/bin/docker-compose
    fi
    chmod +x /usr/bin/docker-compose

    if docker-compose --version ;then
        ${COLOR_SUCCESS}"Docker Compose 安装完成"${END} 
    else
        ${COLOR_FAILURE}"Docker compose 安装失败"${END}
        exit
    fi  
}

install_harbor() {
    ${COLOR_SUCCESS}"开始安装 Harbor....."${END}
    sleep 5
    #下载文件
    if [ ! -e harbor-offline-installer-v${HARBOR_VERSION}.tgz ];then
        wget https://github.com/goharbor/harbor/releases/download/v${HARBOR_VERSION}/harbor-offline-installer-v${HARBOR_VERSION}.tgz || ${COLOR_FAILURE} "下载失败!" ${END}
    fi
    #[ -d ${HARBOR_BASE} ] ||  mkdir ${HARBOR_BASE}
    tar xvf harbor-offline-installer-v${HARBOR_VERSION}.tgz  -C ${HARBOR_BASE}
    cd ${HARBOR_BASE}/harbor

    #编辑配置文件
    cp harbor.yml.tmpl harbor.yml
    sed -ri "/^hostname/s/reg.mydomain.com/${HARBOR_NAME}/" harbor.yml
    sed -ri "/^https/s/(https:)/#\1/" harbor.yml
    sed -ri "s/(port: 443)/#\1/" harbor.yml
    sed -ri "/certificate:/s/(.*)/#\1/" harbor.yml
    sed -ri "/private_key:/s/(.*)/#\1/" harbor.yml
    sed -ri "s/Harbor12345/${HARBOR_ADMIN_PASSWORD}/" harbor.yml
    sed -i 's#^data_volume: /data#data_volume: /data/harbor#' harbor.yml

    ${HARBOR_BASE}/harbor/install.sh && ${COLOR_SUCCESS}"Harbor 安装完成"${END} ||  ${COLOR_FAILURE}"Harbor 安装失败"${END}

    cat > /lib/systemd/system/harbor.service << EOF
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f  ${HARBOR_BASE}/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f ${HARBOR_BASE}/harbor/docker-compose.yml down

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable --now harbor &> /dev/null || ${COLOR}"Harbor已配置为开机自动启动"${END}

    if [ $?  -eq 0 ];then
        echo
        color "Harbor安装完成!" 0
        echo "-------------------------------------------------------------------"
        echo -e "请访问链接: \E[32;1mhttp://${HARBOR_IP}/\E[0m"
        echo -e "用户和密码: \E[32;1madmin/${HARBOR_ADMIN_PASSWORD}\E[0m"
    else
        color "Harbor安装失败!" 1
        exit
    fi
}

docker info &> /dev/null && ${COLOR_FAILURE}"Docker已安装"${END} || install_docker
docker-compose --version &> /dev/null && ${COLOR_FAILURE}"Docker Compose已安装"${END} || install_docker_compose
install_harbor

[root@rocky8 ~]$ sh /data/scripts/install_harbor.sh

4.2 在Harbor服务器(10.0.0.18)上配置https

4.2.1 生成Harbor服务器证书

#生成ca的私钥
openssl genrsa -out ca.key 4096

#生成ca的自签名证书
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Jiangsu/L=Nanjing/O=example/OU=Personal/CN=yanlinux.org" \
-key ca.key \
-out ca.crt

#生成harbor主机的私钥
openssl genrsa -out harbor1.yanlinux.org.key 4096

#生成harbor主机的证书申请
openssl req -new -sha512 \
-subj "/C=CN/ST=Jiangsu/L=Nanjing/O=example/OU=Personal/CN=harbor1.yanlinux.org" \
-key harbor1.yanlinux.org.key \
-out harbor1.yanlinux.org.csr

#创建x509 v3扩展文件(新版新增的要求)
cat > v3.txt <<EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=yanlinux.org
DNS.2=yanlinux
DNS.3=harbor1.yanlinux.org  #域名
EOF

#给harbor主机颁发证书
openssl x509 -req -sha512 -days 3650 \
-extfile v3.txt \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in harbor1.yanlinux.org.csr \
-out harbor1.yanlinux.org.crt

#最终文件
ca.crt  ca.srl                   harbor1.yanlinux.org.csr  v3.txt
ca.key  harbor1.yanlinux.org.crt  harbor1.yanlinux.org.key

4.2.2 配置Harbor服务器使用证书

mkdir /data/harbor/certs/

#拷贝证书文件
cp harbor1.yanlinux.org.crt harbor1.yanlinux.org.key /data/harbor/certs/

#修改配置,加上https认证
vim /usr/local/harbor/harbor.yml
......
# https related config
https:
  # https port for harbor, default is 443
  port: 443
  # The path of cert and key files for nginx
  certificate: /data/harbor/certs/harbor1.yanlinux.org.crt
  private_key: /data/harbor/certs/harbor1.yanlinux.org.key
......

#使配置生效
cd /usr/local/harbor
./prepare; docker-compose down -v; docker-compose up -d

打开网址就会跳转到https

4.3 在Docker服务器端(10.0.0.8)下载CA的证书并上传镜像

直接登录和上传下载镜像会报错

[root@rocky8 ~]$ vi /etc/hosts
10.0.0.18 harbor1.yanlinux.org

#没有证书验证,直接登录失败
[root@rocky8 ~]$ docker login harbor1.yanlinux.org
Username: admin
Password: 
Error response from daemon: Get "https://harbor1.yanlinux.org/v2/": x509: certificate signed by unknown authority

#拉取失败
[root@rocky8 ~]$ docker pull harbor1.yanlinux.org/test/nginx:1.22.1-20230222
Error response from daemon: Get "https://harbor1.yanlinux.org/v2/": x509: certificate signed by unknown authority

在docker服务器端使用证书文件

#在harbor服务器端,转换harbor的crt证书文件为cert后缀,docker识别crt文件为CA证书,cert为客户端证书
[root@rocky8 certs]$ openssl x509 -inform PEM -in harbor1.yanlinux.org.crt -out harbor1.yanlinux.org.cert
[root@rocky8 certs]$ ll harbor1.yanlinux.org.c*rt
-rw-r--r-- 1 root root 2134 Feb 28 22:24 harbor1.yanlinux.org.cert
-rw-r--r-- 1 root root 2134 Feb 28 21:46 harbor1.yanlinux.org.crt

#两个文件一样,直接cp -a harbor1.yanlinux.org.crt harbor1.yanlinux.org.cert就行
[root@rocky8 certs]$ md5sum harbor1.yanlinux.org.cert harbor1.yanlinux.org.crt
23ef17b3e9fa2069fe5a190dd8b428de  harbor1.yanlinux.org.cert
23ef17b3e9fa2069fe5a190dd8b428de  harbor1.yanlinux.org.crt


#在docker服务端下载证书
[root@rocky8 ~]$ mkdir /etc/docker/certs.d/harbor1.yanlinux.org/ -p
[root@rocky8 ~]$ cd /etc/docker/certs.d/harbor1.yanlinux.org/
[root@rocky8 ~]$ scp 10.0.0.18:/root/certs/{harbor1.yanlinux.org.cert,harbor1.yanlinux.org.key,ca.crt} /etc/docker/certs.d/harbor1.yanlinux.org/


#在harbor服务器上拷贝证书到/etc/docker下,实现harbor服务器的上传与下载镜像
[root@rocky8 harbor1.yanlinux.org]$ scp -r /etc/docker/certs.d/ 10.0.0.18:/etc/docker/
[root@rocky8 ~]$ systemctl restart docker


#登录账户
[root@rocky8 ~]$ docker login harbor1.yanlinux.org

#打标签
[root@rocky8 ~]$ docker tag alpine-base:3.17.2 harbor1.yanlinux.org/test/alpine-base:3.17.2
[root@rocky8 ~]$ docker tag nginx-alpine:1.22.1 harbor1.yanlinux.org/test/nginx-alpine:1.22.1
[root@rocky8 ~]$ docker tag alpine-jdk:8u202 harbor1.yanlinux.org/test/alpine-jdk:8u202
[root@rocky8 ~]$ docker tag tomcat-base:v8.5.85 harbor1.yanlinux.org/test/tomcat-base:v8.5.85
[root@rocky8 ~]$ docker tag haproxy-alpine:2.1.2 harbor1.yanlinux.org/test/haproxy-alpine:2.1.2

#上传镜像
[root@rocky8 ~]$ docker push harbor1.yanlinux.org/test/alpine-base:3.17.2
The push refers to repository [harbor1.yanlinux.org/test/alpine-base]
87c8bbf9e2e8: Pushed 
0ba47f277eb9: Pushed 
7cd52847ad77: Pushed 
3.17.2: digest: sha256:d2aaa9d3e26da43e5b83d02b92aab403f33e9d4c9a3e9171a14ef314692e4a7a size: 947
[root@rocky8 ~]$ docker push harbor1.yanlinux.org/test/nginx-alpine:1.22.1
The push refers to repository [harbor1.yanlinux.org/test/nginx-alpine]
fa80f3c76ef6: Pushed 
01c65a043850: Pushed 
adbe8696b1b4: Pushed 
1e356a844716: Pushed 
ebb41e59056a: Pushed 
0ba47f277eb9: Mounted from test/alpine-base 
7cd52847ad77: Mounted from test/alpine-base 
1.22.1: digest: sha256:104304b5133de8acd1978485c2d980748dab7314d267d29b4278f22573010058 size: 1784
[root@rocky8 ~]$ docker push harbor1.yanlinux.org/test/alpine-jdk:8u202
The push refers to repository [harbor1.yanlinux.org/test/alpine-jdk]
d88c104af48e: Pushed 
4236564ab151: Pushed 
31af46d91eef: Pushed 
87c8bbf9e2e8: Mounted from test/alpine-base 
0ba47f277eb9: Mounted from test/nginx-alpine 
7cd52847ad77: Mounted from test/nginx-alpine 
8u202: digest: sha256:6a93df44d46e757dda66a6c2f8ea28c11d3954d3c714392b608c40f45b2e2413 size: 1574
[root@rocky8 ~]$ docker push harbor1.yanlinux.org/test/tomcat-base:v8.5.85
The push refers to repository [harbor1.yanlinux.org/test/tomcat-base]
6d1a20593ad3: Pushed 
8d7f5b279153: Pushed 
0abb32fe3733: Pushed 
d88c104af48e: Mounted from test/alpine-jdk 
4236564ab151: Mounted from test/alpine-jdk 
31af46d91eef: Mounted from test/alpine-jdk 
87c8bbf9e2e8: Mounted from test/alpine-jdk 
0ba47f277eb9: Mounted from test/alpine-jdk 
7cd52847ad77: Mounted from test/alpine-jdk 
v8.5.85: digest: sha256:a19bb6ff4a407cbd9881a27b8ca412b6bd45d5fd0b8bff35e6a6d759813fb273 size: 2200
[root@rocky8 ~]$ docker push harbor1.yanlinux.org/test/haproxy-alpine:2.1.2
The push refers to repository [harbor1.yanlinux.org/test/haproxy-alpine]
406ce5ba5219: Pushed 
3ecff3848c3e: Pushed 
89180f31278f: Pushed 
87c8bbf9e2e8: Mounted from test/tomcat-base 
0ba47f277eb9: Mounted from test/tomcat-base 
7cd52847ad77: Mounted from test/tomcat-base 
2.1.2: digest: sha256:bbf660062436f982e820d2daacb8fcd1d83ecc06115e178bfe094b8c4f513066 size: 1576

查看仓库上传的镜像

4.4 在客户端下载镜像(10.0.0.38 安装docker)

直接登录和上传下载镜像会报错

[root@rocky8 ~]$ vi /etc/hosts
10.0.0.18 harbor1.yanlinux.org

#没有证书验证,直接登录失败
[root@rocky8 ~]$ docker login harbor1.yanlinux.org
Username: admin
Password: 
Error response from daemon: Get "https://harbor1.yanlinux.org/v2/": x509: certificate signed by unknown authority

#拉取失败
[root@rocky8 ~]$ docker pull harbor1.yanlinux.org/test/nginx:1.22.1-20230222
Error response from daemon: Get "https://harbor1.yanlinux.org/v2/": x509: certificate signed by unknown authority

配置Docker客户端使用证书文件

#在docker客户端下载证书
[root@rocky8 ~]$ mkdir /etc/docker/certs.d/harbor1.yanlinux.org/ -p
[root@rocky8 ~]$ cd /etc/docker/certs.d/harbor1.yanlinux.org/
[root@rocky8 harbor1.yanlinux.org]$ scp 10.0.0.18:/root/certs/{harbor1.yanlinux.org.cert,harbor1.yanlinux.org.key,ca.crt} /etc/docker/certs.d/harbor1.yanlinux.org/
[root@rocky8 ~]$ systemctl restart docker

拉取镜像

[root@rocky8 ~]$ docker pull harbor1.yanlinux.org/test/haproxy-alpine:2.1.2
[root@rocky8 ~]$ docker pull harbor1.yanlinux.org/test/tomcat-base:v8.5.85
[root@rocky8 ~]$ docker pull harbor1.yanlinux.org/test/alpine-jdk:8u202
[root@rocky8 ~]$ docker pull harbor1.yanlinux.org/test/nginx-alpine:1.22.1
[root@rocky8 ~]$ docker pull harbor1.yanlinux.org/test/alpine-base:3.17.2

[root@rocky8 ~]$ docker images 
REPOSITORY                                 TAG       IMAGE ID       CREATED             SIZE
harbor1.yanlinux.org/test/haproxy-alpine   2.1.2     9eeb5cb28dbe   About an hour ago   226MB
harbor1.yanlinux.org/test/tomcat-base      v8.5.85   f5a9ab5c83ab   2 hours ago         615MB
harbor1.yanlinux.org/test/alpine-jdk       8u202     a38ecf1969fd   3 hours ago         600MB
harbor1.yanlinux.org/test/alpine-base      3.17.2    b3e65dab1347   3 hours ago         197MB
harbor1.yanlinux.org/test/nginx-alpine     1.22.1    7f619fd93a01   5 hours ago         213MB

4.5 运行nginx服务

[root@rocky8 ~]$ docker run -d --name web01 -p 80:80 harbor1.yanlinux.org/test/nginx-alpine:1.22.1 
122ce510bc25d74325525aae4ed9d4a10296cb525fb893aa3c6635ebda7cd936

查看网页信息

5 docker的常见网络模式

Docker 的网络支持5种网络模式:

  • Bridge模式: 默认模式。在这种模式下,Docker 容器连接到一个 Docker 网桥,该网桥通过宿主机的物理网络接口与外部网络通信。每个容器都分配了一个独立的 IP 地址。
  • Host模式: 在这种模式下,容器共享宿主机的网络命名空间。这使得容器可以直接访问宿主机上的网络接口,而不需要通过网络桥接。
  • None 模式: 这种模式在容器中禁用了所有的网络连接。通常用于运行与网络无关的应用程序。
  • container:它是bridge和host模式的合体,优先以bridge方式启动启动第一个容器,后面的所有容器启动时,均指定网络模式为container,它们均共享第一个容器的网络资源,除了网络资源,其他资源,容器彼此之间依然是相互隔离的。
  • user-defined模式网络:
    • Overlay 模式: 用于将多个 Docker 宿主机连接在一起的模式。这种模式在分布式应用程序的场景中非常有用,可以将多个容器分布在不同的主机上,并以透明的方式通信。
    • Macvlan 模式: 这种模式允许 Docker 容器具有自己的 MAC 地址,因此它们可以像物理机器一样直接与网络交互。这种模式通常用于在 Docker 容器中运行网络应用程序。

6 用docker-compose 将2中构建的镜像组合起来提供服务。

#创建业务目录
[root@rocky8 ~]$ cd /data/docker-compose/
[root@rocky8 docker-compose]$ mkdir haproxy/web{1,2} -p
[root@rocky8 docker-compose]$ cd haproxy

#制作两个nginx容器的测试页面
[root@rocky8 haproxy]$ echo welcome to web1 docker websit! > web1/index.html
[root@rocky8 haproxy]$ echo welcome to web2 docker websit! > web2/index.html

#制作haproxy配置文件
[root@rocky8 haproxy]$ cat haproxy.cfg
#--------------全局配置----------------
global
    log 127.0.0.1 local0  info
    #log loghost local0 info
    maxconn 20480
#chroot /usr/local/haproxy
    pidfile /var/run/haproxy.pid
    #maxconn 4000
    user haproxy
    group haproxy
    daemon
#---------------------------------------------------------------------
#common defaults that all the 'listen' and 'backend' sections will
#use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode http
    log global
    option dontlognull
    option httpclose
    option httplog
    #option forwardfor
    option redispatch
    balance roundrobin
    timeout connect 10s
    timeout client 10s
    timeout server 10s
    timeout check 10s
    maxconn 60000
    retries 3
#--------------统计页面配置------------------
listen admin_stats
    bind 0.0.0.0:8189
    stats enable
    mode http
    log global
    stats uri /haproxy_stats
    stats realm Haproxy\ Statistics
    stats auth admin:admin
    #stats hide-version
    stats admin if TRUE
    stats refresh 30s
#---------------web设置-----------------------
listen webcluster
    bind 0.0.0.0:80
    mode http
    #option httpchk GET /index.html
    log global
    maxconn 3000
    balance roundrobin
    cookie SESSION_COOKIE insert indirect nocache
    server server1 web1:80 check inter 2000 fall 5
    server server2 web2:80 check inter 2000 fall 5

#制作docker compose文件
[root@rocky8 haproxy]$ vi docker-compose.yml
version: '3.0'
services:
  web1:
    image: 'registry.cn-hangzhou.aliyuncs.com/yanlinux/nginx-alpine:1.22.1'
    container_name: web1
    restart: unless-stopped
    ports:
      - 80
    volumes:
      - './web1:/data/html'
  web2:
    image: 'registry.cn-hangzhou.aliyuncs.com/yanlinux/nginx-alpine:1.22.1'
    container_name: web2
    restart: unless-stopped
    ports:
      - 80
    volumes:
      - './web2:/data/html'
  haproxy:
    depends_on:
      - web1
      - web2
    image: 'registry.cn-hangzhou.aliyuncs.com/yanlinux/haproxy-alpine:2.1.2'
    volumes:
      - './haproxy.cfg:/usr/local/haproxy/conf/haproxy.cfg:ro'
    ports:
      - '80:80'

#运行docker-compose文件
[root@rocky8 haproxy]$ docker-compose up -d
[+] Running 3/3
 ⠿ Container web2               Running                                                                 
 ⠿ Container web1               Running                                                                 
 ⠿ Container haproxy-haproxy-1  Started

 [root@rocky8 haproxy]$ docker ps
CONTAINER ID        IMAGE                                                             COMMAND                  CREATED             STATUS              PORTS                          NAMES
d3b7e38da5f8        registry.cn-hangzhou.aliyuncs.com/yanlinux/haproxy-alpine:2.1.2   "/entrypoint.sh"         4 minutes ago       Up 4 minutes        0.0.0.0:80->80/tcp, 8189/tcp   haproxy-haproxy-1
a0697df397c6        registry.cn-hangzhou.aliyuncs.com/yanlinux/nginx-alpine:1.22.1    "/bin/sh -c '/apps/n…"   10 minutes ago      Up 10 minutes       0.0.0.0:32771->80/tcp          web1
71c7f6dfcf0c        registry.cn-hangzhou.aliyuncs.com/yanlinux/nginx-alpine:1.22.1    "/bin/sh -c '/apps/n…"   10 minutes ago      Up 10 minutes       0.0.0.0:32770->80/tcp          web2

网页查看负载均衡实现


  转载请注明: 焱黎的博客 架构第四周

  目录