CENTOS上的网络安全工具(十三)搬到Docker上(1)?

news2025/8/3 2:45:24

        鉴于在集群上构建安全工具的情况越来越频繁,并且现在一些安全工具也提供了Docker形式的部署,再停留在虚拟机+yum的部署方式似乎已经不太合时宜了。所以在再一次碰到一个安全工具需要使用docker安装的时候,我们毅然(被逼)转向了Docker。希望以后能够就在Docker上部署安全工具吧。

        一、CentOS-stream-8上的Docker安装

        Docker的安装还是比较简单的,尤其是在线上的情况下,国内也有镜像网站直接提供了安装脚本,但是长期被各种安装步骤折磨的我们还是选择了手撸,以便在某一步出现问题的时候能够及时定位。

        1.添加Docker镜像库

        首先要将Docker的镜像库添加到centos中。鉴于最近终于搬进了崭新的办公区,上网环境得到大幅改善,所以就不去折腾离线安装了(如果需要离线,应该方法和我们之前在没有网络时痛苦折腾的情况相当)。

        使用yum-config-manager --add-repo命令,可以将官方repo地址添加到yum.repos.d目录下,成功完成命令后,可以在该目录下发现一个名为docker-ce.repo的文件,cat一下可以观察到该命令导入的docker repo仓库地址。

[root@localhost ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
添加仓库自:https://download.docker.com/linux/centos/docker-ce.repo
[root@localhost ~]# cd /etc/yum.repos.d/
[root@localhost yum.repos.d]# ls
CentOS-Stream-AppStream.repo      CentOS-Stream-Extras.repo            CentOS-Stream-PowerTools.repo        docker-ce.repo
CentOS-Stream-BaseOS.repo         CentOS-Stream-HighAvailability.repo  CentOS-Stream-RealTime.repo
CentOS-Stream-Debuginfo.repo      CentOS-Stream-Media.repo             CentOS-Stream-ResilientStorage.repo
CentOS-Stream-Extras-common.repo  CentOS-Stream-NFV.repo               CentOS-Stream-Sources.repo
[root@localhost yum.repos.d]# cat docker-ce.repo
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

[docker-ce-stable-debuginfo]
name=Docker CE Stable - Debuginfo $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/stable
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

[docker-ce-stable-source]
name=Docker CE Stable - Sources
baseurl=https://download.docker.com/linux/centos/$releasever/source/stable
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

[docker-ce-test]
name=Docker CE Test - $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/test
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

[docker-ce-test-debuginfo]
name=Docker CE Test - Debuginfo $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/test
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

[docker-ce-test-source]
name=Docker CE Test - Sources
baseurl=https://download.docker.com/linux/centos/$releasever/source/test
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

[docker-ce-nightly]
name=Docker CE Nightly - $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

[docker-ce-nightly-debuginfo]
name=Docker CE Nightly - Debuginfo $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

[docker-ce-nightly-source]
name=Docker CE Nightly - Sources
baseurl=https://download.docker.com/linux/centos/$releasever/source/nightly
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

        2.清除centos中的podman

        一般来说,Centos中默认安装了podman,centos的自带“docker”,据说连命令格式都一样,没有深究。

[root@localhost ~]# rpm -qa|grep 'podman'
podman-4.2.0-1.module_el8.7.0+1216+b022c01d.x86_64
cockpit-podman-53-1.module_el8.7.0+1216+b022c01d.noarch
podman-catatonit-4.2.0-1.module_el8.7.0+1216+b022c01d.x86_64
[root@localhost ~]# rpm -qa|grep 'buildah'
buildah-1.27.0-2.module_el8.7.0+1216+b022c01d.x86_64
[root@localhost ~]# 

        还有buildah,一并删掉了之。否则安装docker的时候会报错。

[root@localhost ~]# yum rm podman buildah
依赖关系解决。
====================================================================================================================================
 软件包                        架构              版本                                                   仓库                   大小
====================================================================================================================================
移除:
 buildah                       x86_64            1:1.24.2-2.module_el8.7.0+1106+45480ee0                @AppStream             30 M
 podman                        x86_64            2:4.0.2-1.module_el8.7.0+1106+45480ee0                 @AppStream             51 M
移除依赖的软件包:
 cockpit-podman                noarch            43-1.module_el8.7.0+1106+45480ee0                      @AppStream            493 k
清除未被使用的依赖关系:
 conmon                        x86_64            2:2.1.0-1.module_el8.7.0+1106+45480ee0                 @AppStream            172 k
 container-selinux             noarch            2:2.180.0-1.module_el8.7.0+1106+45480ee0               @AppStream             54 k
 containers-common             x86_64            2:1-23.module_el8.7.0+1106+45480ee0                    @AppStream            361 k
 criu                          x86_64            3.15-3.module_el8.6.0+926+8bef8ae7                     @AppStream            1.4 M
 fuse-overlayfs                x86_64            1.8.2-1.module_el8.7.0+1106+45480ee0                   @AppStream            145 k
 fuse3                         x86_64            3.3.0-15.el8                                           @anaconda             100 k
 fuse3-libs                    x86_64            3.3.0-15.el8                                           @anaconda             274 k
 libnet                        x86_64            1.1.6-15.el8                                           @AppStream            170 k
 libslirp                      x86_64            4.4.0-1.module_el8.6.0+926+8bef8ae7                    @AppStream            134 k
 podman-catatonit              x86_64            2:4.0.2-1.module_el8.7.0+1106+45480ee0                 @AppStream            764 k
 runc                          x86_64            1:1.0.3-3.module_el8.7.0+1106+45480ee0                 @AppStream             11 M
 shadow-utils-subid            x86_64            2:4.6-16.el8                                           @anaconda             205 k
 slirp4netns                   x86_64            1.1.8-2.module_el8.7.0+1106+45480ee0                   @AppStream             98 k

事务概要
====================================================================================================================================
移除  16 软件包

将会释放空间:96 M
确定吗?[y/N]: y
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
  准备中  :                                                                                                                     1/1 
  运行脚本: buildah-1:1.24.2-2.module_el8.7.0+1106+45480ee0.x86_64                                                              1/1 
  删除    : buildah-1:1.24.2-2.module_el8.7.0+1106+45480ee0.x86_64                                                             1/16 
  删除    : cockpit-podman-43-1.module_el8.7.0+1106+45480ee0.noarch                                                            2/16 
  删除    : podman-2:4.0.2-1.module_el8.7.0+1106+45480ee0.x86_64                                                               3/16 
  运行脚本: podman-2:4.0.2-1.module_el8.7.0+1106+45480ee0.x86_64                                                               3/16 
  删除    : containers-common-2:1-23.module_el8.7.0+1106+45480ee0.x86_64                                                       4/16 
  删除    : container-selinux-2:2.180.0-1.module_el8.7.0+1106+45480ee0.noarch                                                  5/16 
  运行脚本: container-selinux-2:2.180.0-1.module_el8.7.0+1106+45480ee0.noarch                                                  5/16 
  删除    : podman-catatonit-2:4.0.2-1.module_el8.7.0+1106+45480ee0.x86_64                                                     6/16 
  删除    : fuse-overlayfs-1.8.2-1.module_el8.7.0+1106+45480ee0.x86_64                                                         7/16 
  删除    : fuse3-3.3.0-15.el8.x86_64                                                                                          8/16 
  删除    : slirp4netns-1.1.8-2.module_el8.7.0+1106+45480ee0.x86_64                                                            9/16 
  删除    : runc-1:1.0.3-3.module_el8.7.0+1106+45480ee0.x86_64                                                                10/16 
  删除    : criu-3.15-3.module_el8.6.0+926+8bef8ae7.x86_64                                                                    11/16 
  删除    : libnet-1.1.6-15.el8.x86_64                                                                                        12/16 
  运行脚本: libnet-1.1.6-15.el8.x86_64                                                                                        12/16 
  删除    : libslirp-4.4.0-1.module_el8.6.0+926+8bef8ae7.x86_64                                                               13/16 
  删除    : fuse3-libs-3.3.0-15.el8.x86_64                                                                                    14/16 
  运行脚本: fuse3-libs-3.3.0-15.el8.x86_64                                                                                    14/16 
  删除    : conmon-2:2.1.0-1.module_el8.7.0+1106+45480ee0.x86_64                                                              15/16 
  删除    : shadow-utils-subid-2:4.6-16.el8.x86_64                                                                            16/16 
  运行脚本: shadow-utils-subid-2:4.6-16.el8.x86_64                                                                            16/16 
  验证    : buildah-1:1.24.2-2.module_el8.7.0+1106+45480ee0.x86_64                                                             1/16 
  验证    : cockpit-podman-43-1.module_el8.7.0+1106+45480ee0.noarch                                                            2/16 
  验证    : conmon-2:2.1.0-1.module_el8.7.0+1106+45480ee0.x86_64                                                               3/16 
  验证    : container-selinux-2:2.180.0-1.module_el8.7.0+1106+45480ee0.noarch                                                  4/16 
  验证    : containers-common-2:1-23.module_el8.7.0+1106+45480ee0.x86_64                                                       5/16 
  验证    : criu-3.15-3.module_el8.6.0+926+8bef8ae7.x86_64                                                                     6/16 
  验证    : fuse-overlayfs-1.8.2-1.module_el8.7.0+1106+45480ee0.x86_64                                                         7/16 
  验证    : fuse3-3.3.0-15.el8.x86_64                                                                                          8/16 
  验证    : fuse3-libs-3.3.0-15.el8.x86_64                                                                                     9/16 
  验证    : libnet-1.1.6-15.el8.x86_64                                                                                        10/16 
  验证    : libslirp-4.4.0-1.module_el8.6.0+926+8bef8ae7.x86_64                                                               11/16 
  验证    : podman-2:4.0.2-1.module_el8.7.0+1106+45480ee0.x86_64                                                              12/16 
  验证    : podman-catatonit-2:4.0.2-1.module_el8.7.0+1106+45480ee0.x86_64                                                    13/16 
  验证    : runc-1:1.0.3-3.module_el8.7.0+1106+45480ee0.x86_64                                                                14/16 
  验证    : shadow-utils-subid-2:4.6-16.el8.x86_64                                                                            15/16 
  验证    : slirp4netns-1.1.8-2.module_el8.7.0+1106+45480ee0.x86_64                                                           16/16 

已移除:
  buildah-1:1.24.2-2.module_el8.7.0+1106+45480ee0.x86_64          cockpit-podman-43-1.module_el8.7.0+1106+45480ee0.noarch           
  conmon-2:2.1.0-1.module_el8.7.0+1106+45480ee0.x86_64            container-selinux-2:2.180.0-1.module_el8.7.0+1106+45480ee0.noarch 
  containers-common-2:1-23.module_el8.7.0+1106+45480ee0.x86_64    criu-3.15-3.module_el8.6.0+926+8bef8ae7.x86_64                    
  fuse-overlayfs-1.8.2-1.module_el8.7.0+1106+45480ee0.x86_64      fuse3-3.3.0-15.el8.x86_64                                         
  fuse3-libs-3.3.0-15.el8.x86_64                                  libnet-1.1.6-15.el8.x86_64                                        
  libslirp-4.4.0-1.module_el8.6.0+926+8bef8ae7.x86_64             podman-2:4.0.2-1.module_el8.7.0+1106+45480ee0.x86_64              
  podman-catatonit-2:4.0.2-1.module_el8.7.0+1106+45480ee0.x86_64  runc-1:1.0.3-3.module_el8.7.0+1106+45480ee0.x86_64                
  shadow-utils-subid-2:4.6-16.el8.x86_64                          slirp4netns-1.1.8-2.module_el8.7.0+1106+45480ee0.x86_64           

完毕!

        3.安装Docker组件

[root@localhost ~]# yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
上次元数据过期检查:0:26:26 前,执行于 2022年11月03日 星期四 06时40分31秒。
依赖关系解决。
====================================================================================================================================
 软件包                            架构           版本                                               仓库                      大小
====================================================================================================================================
安装:
 containerd.io                     x86_64         1.6.9-3.1.el8                                      docker-ce-stable          33 M
 docker-ce                         x86_64         3:20.10.21-3.el8                                   docker-ce-stable          21 M
 docker-ce-cli                     x86_64         1:20.10.21-3.el8                                   docker-ce-stable          30 M
 docker-compose-plugin             x86_64         2.12.2-3.el8                                       docker-ce-stable          10 M
安装依赖关系:
 container-selinux                 noarch         2:2.189.0-1.module_el8.7.0+1216+b022c01d           appstream                 60 k
 docker-ce-rootless-extras         x86_64         20.10.21-3.el8                                     docker-ce-stable         4.6 M
 fuse-overlayfs                    x86_64         1.9-1.module_el8.7.0+1216+b022c01d                 appstream                 73 k
 fuse3                             x86_64         3.3.0-16.el8                                       baseos                    54 k
 fuse3-libs                        x86_64         3.3.0-16.el8                                       baseos                    95 k
 libcgroup                         x86_64         0.41-19.el8                                        baseos                    70 k
 libslirp                          x86_64         4.4.0-1.module_el8.7.0+1216+b022c01d               appstream                 70 k
 slirp4netns                       x86_64         1.2.0-2.module_el8.7.0+1216+b022c01d               appstream                 54 k
安装弱的依赖:
 docker-scan-plugin                x86_64         0.21.0-3.el8                                       docker-ce-stable         3.8 M

事务概要
====================================================================================================================================
安装  13 软件包

总下载:103 M
安装大小:394 M
下载软件包:
(1/13): libslirp-4.4.0-1.module_el8.7.0+1216+b022c01d.x86_64.rpm                                    1.0 MB/s |  70 kB     00:00    
(2/13): container-selinux-2.189.0-1.module_el8.7.0+1216+b022c01d.noarch.rpm                         819 kB/s |  60 kB     00:00    
(3/13): fuse-overlayfs-1.9-1.module_el8.7.0+1216+b022c01d.x86_64.rpm                                947 kB/s |  73 kB     00:00    
(4/13): slirp4netns-1.2.0-2.module_el8.7.0+1216+b022c01d.x86_64.rpm                                 2.5 MB/s |  54 kB     00:00    
(5/13): fuse3-3.3.0-16.el8.x86_64.rpm                                                               2.5 MB/s |  54 kB     00:00    
(6/13): fuse3-libs-3.3.0-16.el8.x86_64.rpm                                                          2.2 MB/s |  95 kB     00:00    
(7/13): libcgroup-0.41-19.el8.x86_64.rpm                                                            2.0 MB/s |  70 kB     00:00    
(8/13): docker-ce-20.10.21-3.el8.x86_64.rpm                                                         248 kB/s |  21 MB     01:26    
(9/13): docker-ce-rootless-extras-20.10.21-3.el8.x86_64.rpm                                         232 kB/s | 4.6 MB     00:20    
(10/13): docker-ce-cli-20.10.21-3.el8.x86_64.rpm                                                    245 kB/s |  30 MB     02:03    
(11/13): docker-scan-plugin-0.21.0-3.el8.x86_64.rpm                                                 239 kB/s | 3.8 MB     00:16    
(12/13): containerd.io-1.6.9-3.1.el8.x86_64.rpm                                                     237 kB/s |  33 MB     02:22    
(13/13): docker-compose-plugin-2.12.2-3.el8.x86_64.rpm                                              258 kB/s |  10 MB     00:40    
------------------------------------------------------------------------------------------------------------------------------------
总计                                                                                                706 kB/s | 103 MB     02:29     
Docker CE Stable - x86_64                                                                           1.9 kB/s | 1.6 kB     00:00    
导入 GPG 公钥 0x621E9F35:
 Userid: "Docker Release (CE rpm) <docker@docker.com>"
 指纹: 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35
 来自: https://download.docker.com/linux/centos/gpg
导入公钥成功
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
  准备中  :                                                                                                                     1/1 
  安装    : docker-scan-plugin-0.21.0-3.el8.x86_64                                                                             1/13 
  运行脚本: docker-scan-plugin-0.21.0-3.el8.x86_64                                                                             1/13 
  安装    : fuse3-libs-3.3.0-16.el8.x86_64                                                                                     2/13 
  运行脚本: fuse3-libs-3.3.0-16.el8.x86_64                                                                                     2/13 
  运行脚本: container-selinux-2:2.189.0-1.module_el8.7.0+1216+b022c01d.noarch                                                  3/13 
  安装    : container-selinux-2:2.189.0-1.module_el8.7.0+1216+b022c01d.noarch                                                  3/13 
  运行脚本: container-selinux-2:2.189.0-1.module_el8.7.0+1216+b022c01d.noarch                                                  3/13 
  安装    : containerd.io-1.6.9-3.1.el8.x86_64                                                                                 4/13 
  运行脚本: containerd.io-1.6.9-3.1.el8.x86_64                                                                                 4/13 
  安装    : fuse3-3.3.0-16.el8.x86_64                                                                                          5/13 
  安装    : fuse-overlayfs-1.9-1.module_el8.7.0+1216+b022c01d.x86_64                                                           6/13 
  运行脚本: fuse-overlayfs-1.9-1.module_el8.7.0+1216+b022c01d.x86_64                                                           6/13 
  安装    : docker-ce-cli-1:20.10.21-3.el8.x86_64                                                                              7/13 
  运行脚本: docker-ce-cli-1:20.10.21-3.el8.x86_64                                                                              7/13 
  运行脚本: libcgroup-0.41-19.el8.x86_64                                                                                       8/13 
  安装    : libcgroup-0.41-19.el8.x86_64                                                                                       8/13 
  运行脚本: libcgroup-0.41-19.el8.x86_64                                                                                       8/13 
  安装    : libslirp-4.4.0-1.module_el8.7.0+1216+b022c01d.x86_64                                                               9/13 
  安装    : slirp4netns-1.2.0-2.module_el8.7.0+1216+b022c01d.x86_64                                                           10/13 
  安装    : docker-ce-rootless-extras-20.10.21-3.el8.x86_64                                                                   11/13 
  运行脚本: docker-ce-rootless-extras-20.10.21-3.el8.x86_64                                                                   11/13 
  安装    : docker-ce-3:20.10.21-3.el8.x86_64                                                                                 12/13 
  运行脚本: docker-ce-3:20.10.21-3.el8.x86_64                                                                                 12/13 
  安装    : docker-compose-plugin-2.12.2-3.el8.x86_64                                                                         13/13 
  运行脚本: docker-compose-plugin-2.12.2-3.el8.x86_64                                                                         13/13 
  运行脚本: container-selinux-2:2.189.0-1.module_el8.7.0+1216+b022c01d.noarch                                                 13/13 
  运行脚本: docker-compose-plugin-2.12.2-3.el8.x86_64                                                                         13/13 
  验证    : container-selinux-2:2.189.0-1.module_el8.7.0+1216+b022c01d.noarch                                                  1/13 
  验证    : fuse-overlayfs-1.9-1.module_el8.7.0+1216+b022c01d.x86_64                                                           2/13 
  验证    : libslirp-4.4.0-1.module_el8.7.0+1216+b022c01d.x86_64                                                               3/13 
  验证    : slirp4netns-1.2.0-2.module_el8.7.0+1216+b022c01d.x86_64                                                            4/13 
  验证    : fuse3-3.3.0-16.el8.x86_64                                                                                          5/13 
  验证    : fuse3-libs-3.3.0-16.el8.x86_64                                                                                     6/13 
  验证    : libcgroup-0.41-19.el8.x86_64                                                                                       7/13 
  验证    : containerd.io-1.6.9-3.1.el8.x86_64                                                                                 8/13 
  验证    : docker-ce-3:20.10.21-3.el8.x86_64                                                                                  9/13 
  验证    : docker-ce-cli-1:20.10.21-3.el8.x86_64                                                                             10/13 
  验证    : docker-ce-rootless-extras-20.10.21-3.el8.x86_64                                                                   11/13 
  验证    : docker-compose-plugin-2.12.2-3.el8.x86_64                                                                         12/13 
  验证    : docker-scan-plugin-0.21.0-3.el8.x86_64                                                                            13/13 

已安装:
  container-selinux-2:2.189.0-1.module_el8.7.0+1216+b022c01d.noarch     containerd.io-1.6.9-3.1.el8.x86_64                          
  docker-ce-3:20.10.21-3.el8.x86_64                                     docker-ce-cli-1:20.10.21-3.el8.x86_64                       
  docker-ce-rootless-extras-20.10.21-3.el8.x86_64                       docker-compose-plugin-2.12.2-3.el8.x86_64                   
  docker-scan-plugin-0.21.0-3.el8.x86_64                                fuse-overlayfs-1.9-1.module_el8.7.0+1216+b022c01d.x86_64    
  fuse3-3.3.0-16.el8.x86_64                                             fuse3-libs-3.3.0-16.el8.x86_64                              
  libcgroup-0.41-19.el8.x86_64                                          libslirp-4.4.0-1.module_el8.7.0+1216+b022c01d.x86_64        
  slirp4netns-1.2.0-2.module_el8.7.0+1216+b022c01d.x86_64              

完毕!
[root@localhost ~]# 

        其中,

        docker-ce:是Docker Engine的Community版本,如果是docker-ee,则是企业版本。免费至上的话,我们还是应该选择ce版本。

        docker-ce-cli:docker引擎的命令行界面(Command Line Interface)的意思。

        containerd.io:对应守护进程containerd,用于与操作系统API进行交互的接口,实质上是用于将容器与操作系统解耦的封装层。

        docker-compose-plugin:不知道是啥,应该和docker-compose相关,docker-compose是一个用于部署的管理多容器应用的工具,通过一个脚本将构筑一个应用的多个服务协同部署。总之说要装,那就装上好了。

        4.打开docker服务

[root@localhost ~]# systemctl start docker.service 
[root@localhost ~]# systemctl status docker.service
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2022-11-03 07:28:55 EDT; 9s ago
     Docs: https://docs.docker.com
 Main PID: 46305 (dockerd)
    Tasks: 10
   Memory: 107.2M
   CGroup: /system.slice/docker.service
           └─46305 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

11月 03 07:28:52 localhost.localdomain dockerd[46305]: time="2022-11-03T07:28:52.958188751-04:00" level=warning msg="Your kernel do>
11月 03 07:28:52 localhost.localdomain dockerd[46305]: time="2022-11-03T07:28:52.958239929-04:00" level=warning msg="Your kernel do>
11月 03 07:28:52 localhost.localdomain dockerd[46305]: time="2022-11-03T07:28:52.958378738-04:00" level=info msg="Loading container>
11月 03 07:28:55 localhost.localdomain dockerd[46305]: time="2022-11-03T07:28:55.004506327-04:00" level=info msg="Default bridge (d>
11月 03 07:28:55 localhost.localdomain dockerd[46305]: time="2022-11-03T07:28:55.154919529-04:00" level=info msg="Firewalld: interf>
11月 03 07:28:55 localhost.localdomain dockerd[46305]: time="2022-11-03T07:28:55.357115017-04:00" level=info msg="Loading container>
11月 03 07:28:55 localhost.localdomain dockerd[46305]: time="2022-11-03T07:28:55.493938906-04:00" level=info msg="Docker daemon" co>
11月 03 07:28:55 localhost.localdomain dockerd[46305]: time="2022-11-03T07:28:55.494372649-04:00" level=info msg="Daemon has comple>
11月 03 07:28:55 localhost.localdomain systemd[1]: Started Docker Application Container Engine.
11月 03 07:28:55 localhost.localdomain dockerd[46305]: time="2022-11-03T07:28:55.514570711-04:00" level=info msg="API listen on /va>
[root@localhost ~]# 

        docker服务需要在组件安装完成后手动打开。打开后使用hello-world镜像测试一下,如下说明docker工作非常正常:

[root@localhost ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete 
Digest: sha256:e18f0a777aefabe047a671ab3ec3eed05414477c951ab1a6f352a06974245fe7
Status: Downloaded newer image for hello-world:latest

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/

[root@localhost ~]# 

        5.安装docker-compose

        前面提到,如果需要部署多服务应用,则需要安装docker-compose。这个需要专门下载:

[root@localhost ~]# curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 23.5M  100 23.5M    0     0   784k      0  0:00:30  0:00:30 --:--:--  705k
[root@localhost ~]# 

        添加执行权限,以及建立快捷方式(软连接)

[root@localhost ~]# chmod +x /usr/local/bin/docker-compose
[root@localhost ~]# ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

        测试安装情况。嗯,这还是个绿色软件……

[root@localhost ~]# docker-compose version
Docker Compose version v2.2.2

        二、Windows上的Docker安装       

     在Windows上安装Docker实在是没法说啥。和Linux上面安装个啥东西装着装着就莫名奇妙失败了不同,在Windows上装个啥属于装着装着莫名其妙就成功了,反正能用就不知道为什么能用的样子。所以当习惯在Linux下面折腾后再回到Windows下面安装的时候,整个就给我整不会了。过程记录不完整,很多都是后来补的,不代表真实流程,凑合着看吧。

        1.Docker Desktop安装

        到docker官方下载Windows版本的安装程序Docker Desktop,会打包安装使用Docker必须的引擎什么的组件。

        早期的时候,由于需要使用hyper-v,docker是木有办法和Vmware共机安装的。好在这个问题现在已经解决了。只需要在Vmware安装的时候选择自动安装WHP(如下图),在Docker安装的时候选择WSL2(如下下图)即可。

在这里插入图片描述

        这样,安装程序会帮助我们把一切都配置好的。当然,如果Vmware仍不可用,那可能需要删掉重装一次。还有就是原先挂起的虚拟机映像,需要放弃挂起状态,“关机”重来一次就可以加载了。

        可以看到,Docker和Vmware都安装完毕后,Hyper-V其实是没有打开的。真正打开的是虚拟机平台、始于Linux的Windows子系统2个组件。

        2.子系统环境配置

        在Windows的Docker中,直接加载Windows的容器,是默认在Windows的子环境中的;但是如果要加载Linux的容器,则需要切换到Linux子系统——这个需要安装。

 

         前面我们说过,Windows下,总是莫名奇妙能够安装成功。当我发现wsl安装成功,但是没有子系统的时候,习惯性的按照Linux的命令习惯,使用wsl的命令行去折腾,忘记了Window下其实有好得多的方法……。

        于是我是这么做的:使用wsl的--help查看了一下帮助,发现这么一个示例命令,然后就执行了一下(当然机器得在线上),然后就安装了ubuntu的子系统,就且过去了…… 事后回想了半天当时是咋就装成功了的-_-!!

        但这么装会有几个问题。一是wsl没有升级到wsl 2,据说这样子系统的运行性能会慢很多;二是在Docker的配置菜单中,会发现子系统其实并没有集成到docker里面来——但是docker确实能够正常运转……如下图: 

       

        正确的安装方式,按照官网的描述,是这样的:

        从这个下载链接下载到wsl的更新安装包(官方名称是Linux内核更新包)进行安装,

https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

        当然我没有这么装,因为我已经装好一个子系统了……再装会报错。所以我继续是这么装的……

        然后不管正确还是“错误”的安装方法,都需要设置wsl2为默认的:

         这样,在docker的配置页面里面就能看到如下的选择项了,都打开就是:

         然而官方是需要继续在Windows商店里下载子系统(Linux分发)进行安装的。

         然而我没有……我也装成功了……感觉反而更简单些……

        三、Docker的基本操作

        如果仅仅是学习测试,或者整个快捷的开发环境,Docker最基本的操作大概只和镜像、容器相关。

        1.镜像 Image

        Docker镜像可以直接从网站上拉取,也可以在已有镜像上继续构造,或者干脆直接从真实系统构造基础镜像。从虚拟机角度看,可以把镜像看作是一个没有装载运行的虚拟机文件,装在运行后就叫做容器了。这里从最简单直接的开始——如何使用已有的镜像启动一个容器(对比用别人的虚拟机存档创建一个虚拟机)。

        (1)Pull 镜像

        Pull镜像有2种做法:一种在命令行方式下单纯使用命令来拉取;一种是结合网页和交互式界面。

        命令行方式:

        首先使用docker查询打算安装的镜像

PS D:\> docker search centos
NAME                                         DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
centos                                       DEPRECATED; The official build of CentOS.       7395      [OK]
kasmweb/centos-7-desktop                     CentOS 7 desktop for Kasm Workspaces            25
couchbase/centos7-systemd                    centos7-systemd images with additional debug…   5                    [OK]
dokken/centos-7                              CentOS 7 image for kitchen-dokken               4
dokken/centos-stream-8                                                                       3
continuumio/centos5_gcc5_base                                                                3
dokken/centos-8                              CentOS 8 image for kitchen-dokken               2
dokken/centos-stream-9                                                                       2
spack/centos6                                CentOS 6 with Spack preinstalled                1
spack/centos7                                CentOS 7 with Spack preinstalled                1
datadog/centos-i386                                                                          0
ustclug/centos                               Official CentOS Image with USTC Mirror          0
dokken/centos-6                              CentOS 6 image for kitchen-dokken               0
bitnami/centos-extras-base                                                                   0
corpusops/centos-bare                        https://github.com/corpusops/docker-images/     0
couchbase/centos-72-java-sdk                                                                 0
corpusops/centos                             centos corpusops baseimage                      0
couchbase/centos-72-jenkins-core                                                             0
couchbase/centos-70-sdk-build                                                                0
couchbase/centos-69-sdk-build                                                                0
couchbase/centos-69-sdk-nodevtoolset-build                                                   0
bitnami/centos-base-buildpack                Centos base compilation image                   0                    [OK]
fnndsc/centos-python3                        Source for a slim Centos-based Python3 image…   0                    [OK]
spack/centos-stream                                                                          0
dokken/centos-5                              EOL DISTRO: For use with kitchen-dokken, Bas…   0
PS D:\>

         然后按照名字拉取:

PS D:\> docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest

        需要一点时间,稍等即可。然后可以使用images命令查看是否拉取成功:

PS D:\> docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
centos       latest    5d0da3dc9764   14 months ago   231MB

        这样就可以了。

        当然上面是在windows cmd里面,在centos里的命令式完全一样。

        使用网页和交互式界面方式:

        在window下,也可以不完全使用命令行这种方式,一定程度上获取信息会更容易一些。

        首先实在hub.docker.com网站上查询需要安装的镜像。

         比如在搜索框中搜索ubuntu。每个镜像都会有下载数统计,一般来说下载得越多越好用,通常这种都会是官方的。点进去。

         右上角这个就是拉取的命令,直接点击复制,在cmd中粘贴运行就可以:

PS D:\> docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
e96e057aae67: Pull complete
Digest: sha256:4b1d0c4a2d2aaf63b37111f34eb9fa89fa1bf53dd6e4ca954d47caebca4005c2
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest

        在docker desktop里面查看,我们拉取的2个images都可以看到:

         如果想安装特定版本的Ubuntu,而不是tag中那个“latest”,在命令行下,是需要明确指定版本号,在网站中,这个命令也可以直接复制过来——只需要点击tags标签,就可以看到所有可用的版本号:

       每个版本的右上角,都有对应的命令格式可以复制使用: 

         2.容器 Container

        把Image运行起来,就是Container。同样我们可以使用命令行和窗口模式。

        命令行模式:

        使用docker run [-it or -d] image_name [cmd]命令可以将镜像运转起来。其中:

        使用-it参数会返回交互式命令行,使用-d参数会直接以daemon方式后台运行。

        image_name就是使用images指令查看到的REPOSITORY:TAG字段,似乎用IMAGE ID也可以,不过我还是习惯用名字。

        cmd是容器载入后默认执行的命令,一般是/bin/bash,如果不行就试试/bin/sh。当然如果是部署了运用,或者想启动服务(/sbin/init),则需要做对应的配置。        

PS D:\> docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
ubuntu       latest    a8780b506fa4   2 weeks ago     77.8MB
centos       latest    5d0da3dc9764   14 months ago   231MB
PS D:\> docker run -it centos:latest /bin/bash
[root@7b68ae2a82ed /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@7b68ae2a82ed /]# pwd
/
[root@7b68ae2a82ed /]#

        看到熟悉的Linux的命令,可以证明容器已经加载起来了。

[root@7b68ae2a82ed /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@7b68ae2a82ed /]# pwd
/
[root@7b68ae2a82ed /]# exit
exit
PS D:\>

        使用exit,则可以退出当前容器。

        使用docker ps命令,或者使用docker container ls命令,可以观察当前已经加载的容器。但是默认情况下,只显示正在运行的容器;exit指令退出后挂起的容器,则需要添加-a选项才能看到。

PS D:\> docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
PS D:\> docker container ls
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
PS D:\> docker ps -a
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS                     PORTS     NAMES
7b68ae2a82ed   centos:latest   "/bin/bash"   20 minutes ago   Exited (0) 4 minutes ago             reverent_maxwell
PS D:\> docker container ls -a
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS                     PORTS     NAMES
7b68ae2a82ed   centos:latest   "/bin/bash"   20 minutes ago   Exited (0) 4 minutes ago             reverent_maxwell
PS D:\>

        再次运行挂起的容器,不能使用run命令,这样会又启动一个新的容器;而是应该使用attach或者exec指令,推荐使用exec指令,这样命令格式和run基本相似。在此之前,需要start挂起的容器。

PS D:\> docker ps -a
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS                     PORTS     NAMES
7b68ae2a82ed   centos:latest   "/bin/bash"   24 minutes ago   Exited (0) 7 minutes ago             reverent_maxwell
PS D:\> docker start reverent_maxwell
reverent_maxwell
PS D:\> docker exec -it reverent_maxwell bash
[root@7b68ae2a82ed /]#

         事实上,run就是create+start+exec的合体而已。

        窗口模式:

        窗口模式很简单,在镜像标签内,点击开始就能启动新的容器

        在容器标签内,各种操作也可以直接点选,包括进入交互式命令行界面。

         三、构建docker镜像

        要用容器构建一个生产环境,那就还有好多内容需要说,但这里就是个入门的话题,所以不深究了——只对如我一般的小白们直觉上会问的第一问题继续尝试——怎么自己构建一个镜像?以及能不能像虚拟机那样完全自己从零安装一个系统,而不是拉取网上别人做好的?

        1. 基于Dockfile构建docker基础映像

        Docker提供了一种标准的Dockerfile方式供我们构造镜像。Dockfile使用FROM确定初始镜像,使用ADD向初始镜像释放tar形式(或其他支持的压缩形式)的文件系统,使用COPY向初始镜像拷贝文件,使用WORKDIR指定默认工作目录,使用RUN指定在构建镜像时、初始镜像加载成功后需要进行的操作,使用CMD指定在镜像加载后默认执行的命令。具体更详细的指令集网络上已经很多介绍了,这里不赘述。

        (1)编写Dockerfile,从scratch开始

        如果从零构建一个Dockerfile,则需要在FROM中指定基础镜像为scratch。这是一个虚拟的镜像,不用(无法)从docker中拉取。实际上,这个镜像是一个基础到不能再基础的“运行时”,仅仅包含了系统的核心运行环境,我们可以写一个程序在其上运转,但只能调用基本的系统API,甚至连一些典型动态库都没有(为此掉了一大坑,这个后面还要折腾)。在Windows上,这等同于系统起来后只加载了API三大模块kernal32,user32和gdi32。从linux的角度来说,就是仅仅加载了内核,连shell都没有(使用bash,sh都不行,也无法进入命令行交互,我猜测是没有shell的,需要自己加)。

        所以,从scatch开始,如果不是ADD一个shell工具集(比如busybox一类),那就只能是自己部署一个应用程序(比如pighello),然后执行它。事实上,执行完成以后,docker也会自动的exit。

        最简单的Dockerfile文件如下所示,从scratch开始,拷贝(对于非压缩文件,ADD的作用和COPY差不多)应用到根目录下,然后启动时默认从根目录执行该文件。

FROM scratch
ADD pighello /
CMD ["/pighello"]

        最好单独建立一个文件夹,将Dockerfile和pighello应用程序放在里面再进行镜像构建。因为build命令会把Dockerfile所在目录的整个文件系统打包发送给docker daemon,如果该目录中没有要放进Docker镜像中的文件,就会付出相当无谓的时间成本。

        pighello我们使用c++编写,功能很简单:

#include <iostream>

using namespace std;

int main()
{
        cout<<"test docker and print hello"<<endl;
}

        编译并执行,如果gcc或者g++命令无法找到,那是没有安装C/C++编译环境。之前的文章有介绍,这里不赘述。将执行文件放入Dockerfile所在目录中,准备构建镜像。

[root@localhost package]# ./pighello
Hello and test Docker Image
[root@localhost package]# pwd
/root/package
[root@localhost package]# ls
Dockerfile  pighello
[root@localhost package]# 

        准备妥当后,使用docker build指令构建镜像,使用-t指令指示镜像名称和tag,注意后面还有一个“.”,表示对当前目录构建(dockerfile和构建素材都在这个我们专门建立的文件夹中):

[root@localhost package]# docker build -t pig:1 .
Sending build context to Docker daemon  20.99kB
Step 1/3 : FROM scratch
 ---> 
Step 2/3 : COPY pighello /
 ---> 510e6b146d3f
Step 3/3 : CMD ["/pighello"]
 ---> Running in 2d8981d781be
Removing intermediate container 2d8981d781be
 ---> 67d63421a207
Successfully built 67d63421a207
Successfully tagged pig:1

        使用images命令查看,可以看到镜像构建成功了。确实很小,只有18.1KB。但是比官方的hello-world还是大了那么一丢丢……

[root@localhost package]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
pig          1         67d63421a207   38 seconds ago   18.1kB
ubuntu       latest    a8780b506fa4   2 weeks ago      77.8MB

        兴奋吧?但是别着急运行,因为运行会报错:),出于文章结构关系,我们这里先不表,跳过去。

        (2)编写Dockerfile,从centos开始

        为了方便理解后面的排坑指南,也为了更好的理解scratch镜像,这里从官方的ubuntu开始再构建一个不很基础的镜像。

        Dockerfile如下:

FROM ubuntu
ADD pighello /
CMD ["/pighello"]

        目录如下:

[root@localhost ~]# mkdir package2
[root@localhost ~]# cd package2
[root@localhost package2]# cp ../package/pighello .
[root@localhost package2]# ls
Dockerfile  pighello

         不同在于将scratch换做了Ubuntu,构建镜像:

[root@localhost package2]# docker build -t pig:2 .
Sending build context to Docker daemon  20.99kB
Step 1/3 : FROM ubuntu
 ---> a8780b506fa4
Step 2/3 : ADD pighello /
 ---> 7f41574af5ac
Step 3/3 : CMD ["/pighello"]
 ---> Running in 2f22f0d94c1b
Removing intermediate container 2f22f0d94c1b
 ---> e3673208057e
Successfully built e3673208057e
Successfully tagged pig:2
[root@localhost package2]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
pig          2         e3673208057e   5 seconds ago    77.8MB
pig          1         67d63421a207   16 minutes ago   18.1kB
ubuntu       latest    a8780b506fa4   2 weeks ago      77.8MB
[root@localhost package2]# 

         这个镜像明显要比scratch大很多,但是比官方镜像就没啥差异了。运行看看:

[root@localhost package2]# docker run pig:2
Hello and test Docker Image

         再交互式进去看看目录是否如我们所想,注意是利用pig:2镜像新启动一个容器。原来那个容器因为设置了CMD是pighello,所以使用start的话,会再次执行pighello退出。

        PS:CMD和ENTRYPOINT的作用大致差不多。区别在于,如果使用ENTRYPOINT设置了默认执行的指令的话,这个run -it /bin/bash的方式也无法替换……。相当于写死了,当然也可以使用docker run --entrypoint /bin/bash pig:2的方式强制替换。

[root@localhost package2]# docker run -it pig:2 /bin/bash
root@36161e59fcdb:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  pighello  proc  root  run  sbin  srv  sys  tmp  usr  var
root@36161e59fcdb:/# 

         可以看到pighello确实是被拷贝到了根目录下的。

        2. 使用容器构建镜像

        事实上,从一个可用的官方基础映像开始(并非scratch,那个空到没法操作),我们可以如构建虚拟机快照一般,通过装载映像并使用容器,在容器中手工添加组件(文件)的方式,构造我们自己的镜像。

        (1)相关docker命令

        

        我们把container的命令帮助放到前面,这里有一个export命令,可以将容器当前的文件系统(这个理解非常重要,我理解容器就是通用的内核,挂载定制的文件系统,运行起来就像一个装了无数软件的windows系统,确实从安全模式启动的那种感觉,如果向完整的用起来,需要大量的手工配置工作)打包成tar文件导出。

        Image的命令帮助放在后面,可以看到,对应export的import实际在Image里面。这里镜像和容器看起来倒是没什么区别——因为容器的文件系统被静态地快照了出来,其实就是镜像。把它挂上一个内核原型起来,就是容器了。

        至于镜像的save和load指令,完全用于导入导出操作静态的镜像本身。我们可以用它来从镜像库中导出文件系统为tar文件,然后拿到别的主机上去用。当然,只要是导出的文件系统,包括export的那个,我想应该都是可以拷走用的。感兴趣可以试试,我没试。

        (2)从官方镜像定制

        我们使用docker启动一个官方的ubuntu镜像,为了方便把pighello拷进去,需要使用docker run -v选项把主机目录挂载进去——不然这个极小的ubuntu系统,连网络都不同,相当麻烦。

        使用ubuntu官方映像启动容器,并且通过挂载方式,将包含pighello的目录mount到容器中,进一步将pighello手工拷贝到根目录下:

[root@localhost package2]# docker run -it -v /root/package:/trans ubuntu bash
root@7b4e71a938c8:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  trans  usr  var
root@7b4e71a938c8:/# cd trans
root@7b4e71a938c8:/trans# ls
Dockerfile  pighello
root@7b4e71a938c8:/trans# cp pighello /
root@7b4e71a938c8:/trans# cd ..
root@7b4e71a938c8:/# ls
bin   dev  home  lib32  libx32  mnt  pighello  root  sbin  sys  trans  var
boot  etc  lib   lib64  media   opt  proc      run   srv   tmp  usr
root@7b4e71a938c8:/# 

         退出容器以后再进来看看,可以看到当挂载的目录卸载后,pighello在根下,和之前我们通过Dokcerfile构建的镜像是一样的。

[root@localhost package2]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED         STATUS                     PORTS     NAMES
7b4e71a938c8   ubuntu    "bash"    2 minutes ago   Exited (0) 5 seconds ago             jovial_bohr
[root@localhost package2]# docker start jovial_bohr 
jovial_bohr
[root@localhost package2]# docker exec -it jovial_bohr bash
root@7b4e71a938c8:/# ls
bin   dev  home  lib32  libx32  mnt  pighello  root  sbin  sys  trans  var
boot  etc  lib   lib64  media   opt  proc      run   srv   tmp  usr
root@7b4e71a938c8:/# 

 (3)导出容器快照,并导入镜像库

        退出我们定制的这个容器。然后使用export,import命令来把它转到快照库中:

[root@localhost package2]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED         STATUS                       PORTS     NAMES
7b4e71a938c8   ubuntu    "bash"    6 minutes ago   Exited (137) 4 seconds ago             jovial_bohr
[root@localhost package2]# 
[root@localhost package2]# 
[root@localhost package2]# docker container export -o pigtar.tar jovial_bohr
[root@localhost package2]# ls
Dockerfile  pighello  pigtar.tar
[root@localhost package2]# 
[root@localhost package2]# 
[root@localhost package2]# docker image import -c 'CMD ["/pighello"]' pigtar.tar pig:3
sha256:0b8ed61b4116a46dfd192d6a01d0504a0761d1b7f71f0af35bd6fb2a3939b3de
[root@localhost package2]# 
[root@localhost package2]# 
[root@localhost package2]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
pig          3         0b8ed61b4116   18 minutes ago   77.8MB
ubuntu       latest    a8780b506fa4   2 weeks ago      77.8MB
centos       latest    5d0da3dc9764   14 months ago    231MB

        使用export指令,指定容器名和tar包的名称,将容器快照导出压缩;再使用import命令,指定tar文件和导入后的镜像名称:tag,将快照导入为镜像,存放到镜像库中。这里要注意的是,需要使用-c选项,指定Dockerfile配置命令来设置镜像的启动默认执行命令,否则镜像还是会去执行/bin/bash,就达不到我们的目的了。

        使用inpect命令查看,可以看到CMD确实配属进去了。执行,确实如我们所设想的那样:

[root@localhost package2]# docker image inspect pig:3
[
    {
        "Id": "sha256:0b8ed61b4116a46dfd192d6a01d0504a0761d1b7f71f0af35bd6fb2a3939b3de",
        "RepoTags": [
            "pig:3"
        ],
        "RepoDigests": [],
        "Parent": "",
        "Comment": "Imported from -",
        "Created": "2022-11-18T03:01:32.296228074Z",
        "Container": "",
        "ContainerConfig": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": null,
            "Cmd": null,
            "Image": "",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
        "DockerVersion": "20.10.21",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": null,
            "Cmd": [
                "/pighello"
            ],
            "Image": "",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 77810623,
        "VirtualSize": 77810623,
        "GraphDriver": {
            "Data": {
                "MergedDir": "/var/lib/docker/overlay2/d76d5fb44f5fcd970e3bc37f7eb3284c390f64a0545de337a7e7218eaf5d8d1b/merged",
                "UpperDir": "/var/lib/docker/overlay2/d76d5fb44f5fcd970e3bc37f7eb3284c390f64a0545de337a7e7218eaf5d8d1b/diff",
                "WorkDir": "/var/lib/docker/overlay2/d76d5fb44f5fcd970e3bc37f7eb3284c390f64a0545de337a7e7218eaf5d8d1b/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:6b261aec0aca8e4afe592db5cd0e0cd08801e07e3ea593a77d4db113c9adb22d"
            ]
        },
        "Metadata": {
            "LastTagTime": "2022-11-17T22:01:32.300887225-05:00"
        }
    }
]
[root@localhost package2]# 
[root@localhost package2]# 
[root@localhost package2]# 
[root@localhost package2]# docker run pig:3
Hello and test Docker Image
[root@localhost package2]# 

         3.docker run:exec /app: no such file or directory 深坑填埋指南

[root@localhost package]# docker run pig:1
exec /pighello: no such file or directory
[root@localhost package]# 

        现在可以来填上面挖好的深坑了。基于scratch构建的基础映像,如果直接拿来运行,会出现找不到文件或目录的错误——而且看起来就像是pighello找不到一样。当然现在我们知道这是不可能的,pighello应该好好的拷贝到了根目录下(只是我是先掉进坑里,然后采用ubuntu官方镜像来验证的)

        (1)根子还在于对scratch的理解

        既然pighello好好的,那到底是什么文件找不到呢?docker官方文档上一个不起眼的字眼暗示了这个问题:

        也就是说,事实上scratch是绝对不会提供C/C++的运行时的;我们提供给scratch的程序,必须使用静态编译的方式,把一家老少都打包带着,才能在容器中真正地跑起来;之所以前面在官方的centos、ubuntu中都能跑,是因为那些静态库、动态库文件已经打包到文件系统里面了。

        然而,如果直接使用-static进行编译,在Centos中会出现“/usr/bin/ld:找不到-lc的”错误:

[root@localhost ~]# gcc pighello.c -o pighello -static
/usr/bin/ld: 找不到 -lc
collect2: 错误:ld 返回 1
[root@localhost ~]# 

         如果是c++,则会遇到的错误更多……:

[root@localhost ~]# g++ pighello.cpp -o pighello -static
/usr/bin/ld: 找不到 -lstdc++
/usr/bin/ld: 找不到 -lm
/usr/bin/ld: 找不到 -lc
collect2: 错误:ld 返回 1
[root@localhost ~]# 

        究其原因,据说是新版的Linux系统不在使用诸如libc.a静态库,而是直接使用libc.so动态库的形式,所以静态链接的时候,无法找到libc.a之类的文件——也就是说,其实找不到的不是pighello,是C/C++运行时的静态链接库。

        如果是ubuntu,官方倒是给出了显见的方法:

        更新一下apt-get,然后装上build-essential就可以。我没试,但是从centos那边试通的情况看,应该没问题。只是Centos下,解决这个问题网上可真是众说纷纭,导致我很长时间都没有get到正确的方法。所谓深坑也……

         (2)Centos的glibc/libstdc++安装

        要实现静态编译c/c++程序,在Centos上需要追加安装glibc和libstdc++这2个静态库。glibc的英文全称为The GNU C Library。glibc是GNU发布的libc库,即c运行库。

        不要问我怎么知道的,我只能哭着说我蒙的,蒙了好久……。只是从网上一个非常片段的线索中知道,要解决这个问题,可以yum安装一个glibc-static的库。然而,使用yum install glibc-static 是无法安装的。且对于c++,更是连这样的线索都没有。

        更多的解决办法,诸如不知从哪里拷贝一个glibc.a,放到/usr/lib64下面,或者建立软连接,或者拷不到的话就去git clone下glibc的源代码,glibc/configure --prefix=安装目录什么的,make然后make list一下等等。我都试过,过程异常复杂,可以说能够解决一个两个问题,当然会因为运行时比较复杂的原因,带来更多的问题。这里就不贴了。

        这里我只说说我是这么蒙的……现有的系统里静态库没有,动态库还是装了的,也许静态库就是动态库的安装包加个“-static”。嗯,如果是这样,我们只需要知道动态库的名字就好了:

[root@localhost ~]# rpm -qa|grep 'glibc'
glibc-langpack-en-2.28-197.el8.x86_64
glibc-gconv-extra-2.28-197.el8.x86_64
glibc-common-2.28-197.el8.x86_64
glibc-langpack-zh-2.28-197.el8.x86_64
glibc-headers-2.28-197.el8.x86_64
glibc-2.28-197.el8.x86_64
glibc-all-langpacks-2.28-197.el8.x86_64
glibc-devel-2.28-197.el8.x86_64
[root@localhost ~]# rpm -qa|grep 'c++'
libsigc++20-2.10.0-6.el8.x86_64
libstdc++-8.5.0-17.el8.x86_64
libstdc++-devel-8.5.0-17.el8.x86_64
gcc-c++-8.5.0-17.el8.x86_64
[root@localhost ~]# 

        需要到centos的库里去搜索:

         当然我需要在CentOS stream 8中去搜索。

        找到的2个库是这样的:

         glibc-static:

         找到对应的版本点进去,也介绍了安装的命令:

        libstdc++:

        同理c++版本在这里:

        可见这两个包都在Powertools库里,使用dnf指定参数就可以安装。当然我们也可以使用yum:

[root@localhost ~]# yum install --enablerepo powertools glibc-static -y
CentOS Stream 8 - PowerTools                                                                         76 kB/s | 5.1 MB     01:08    
上次元数据过期检查:0:00:24 前,执行于 2022年11月17日 星期四 23时44分48秒。
依赖关系解决。
====================================================================================================================================
 软件包                                架构                     版本                             仓库                          大小
====================================================================================================================================
安装:
 glibc-static                          x86_64                   2.28-216.el8                     powertools                   2.1 M
升级:
 glibc                                 x86_64                   2.28-216.el8                     baseos                       2.2 M
 glibc-all-langpacks                   x86_64                   2.28-216.el8                     baseos                        26 M
 glibc-common                          x86_64                   2.28-216.el8                     baseos                       1.0 M
 glibc-devel                           x86_64                   2.28-216.el8                     baseos                        82 k
 glibc-gconv-extra                     x86_64                   2.28-216.el8                     baseos                       1.5 M
 glibc-headers                         x86_64                   2.28-216.el8                     baseos                       487 k
 glibc-langpack-en                     x86_64                   2.28-216.el8                     baseos                       825 k
 glibc-langpack-zh                     x86_64                   2.28-216.el8                     baseos                       2.2 M
安装依赖关系:
 libxcrypt-static                      x86_64                   4.1.1-6.el8                      powertools                    56 k

事务概要
====================================================================================================================================
安装  2 软件包
升级  8 软件包

总下载:36 M
下载软件包:
(1/10): glibc-2.28-216.el8.x86_64.rpm                                                               2.0 MB/s | 2.2 MB     00:01    
(2/10): glibc-all-langpacks-2.28-216.el8.x86_64.rpm                                                  12 MB/s |  26 MB     00:02    
(3/10): glibc-common-2.28-216.el8.x86_64.rpm                                                        6.8 MB/s | 1.0 MB     00:00    
(4/10): glibc-devel-2.28-216.el8.x86_64.rpm                                                         614 kB/s |  82 kB     00:00    
(5/10): glibc-gconv-extra-2.28-216.el8.x86_64.rpm                                                   8.5 MB/s | 1.5 MB     00:00    
(6/10): glibc-headers-2.28-216.el8.x86_64.rpm                                                       3.2 MB/s | 487 kB     00:00    
(7/10): libxcrypt-static-4.1.1-6.el8.x86_64.rpm                                                      13 kB/s |  56 kB     00:04    
(8/10): glibc-langpack-en-2.28-216.el8.x86_64.rpm                                                   1.5 MB/s | 825 kB     00:00    
(9/10): glibc-langpack-zh-2.28-216.el8.x86_64.rpm                                                   1.1 MB/s | 2.2 MB     00:01    
[MIRROR] glibc-static-2.28-216.el8.x86_64.rpm: Curl error (18): Transferred a partial file for http://mirrors.njupt.edu.cn/centos/8-stream/PowerTools/x86_64/os/Packages/glibc-static-2.28-216.el8.x86_64.rpm [transfer closed with 1967786 bytes remaining to read]
(10/10): glibc-static-2.28-216.el8.x86_64.rpm                                                        61 kB/s | 2.1 MB     00:34    
------------------------------------------------------------------------------------------------------------------------------------
总计                                                                                                1.0 MB/s |  36 MB     00:36     
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
  准备中  :                                                                                                                     1/1 
  升级    : glibc-all-langpacks-2.28-216.el8.x86_64                                                                            1/18 
  升级    : glibc-common-2.28-216.el8.x86_64                                                                                   2/18 
  升级    : glibc-gconv-extra-2.28-216.el8.x86_64                                                                              3/18 
  运行脚本: glibc-gconv-extra-2.28-216.el8.x86_64                                                                              3/18 
  升级    : glibc-langpack-en-2.28-216.el8.x86_64                                                                              4/18 
  升级    : glibc-langpack-zh-2.28-216.el8.x86_64                                                                              5/18 
  运行脚本: glibc-2.28-216.el8.x86_64                                                                                          6/18 
  升级    : glibc-2.28-216.el8.x86_64                                                                                          6/18 
  运行脚本: glibc-2.28-216.el8.x86_64                                                                                          6/18 
  运行脚本: glibc-headers-2.28-216.el8.x86_64                                                                                  7/18 
  升级    : glibc-headers-2.28-216.el8.x86_64                                                                                  7/18 
  升级    : glibc-devel-2.28-216.el8.x86_64                                                                                    8/18 
  运行脚本: glibc-devel-2.28-216.el8.x86_64                                                                                    8/18 
  安装    : libxcrypt-static-4.1.1-6.el8.x86_64                                                                                9/18 
  安装    : glibc-static-2.28-216.el8.x86_64                                                                                  10/18 
  运行脚本: glibc-devel-2.28-197.el8.x86_64                                                                                   11/18 
  清理    : glibc-devel-2.28-197.el8.x86_64                                                                                   11/18 
  清理    : glibc-headers-2.28-197.el8.x86_64                                                                                 12/18 
  清理    : glibc-gconv-extra-2.28-197.el8.x86_64                                                                             13/18 
  运行脚本: glibc-gconv-extra-2.28-197.el8.x86_64                                                                             13/18 
  清理    : glibc-all-langpacks-2.28-197.el8.x86_64                                                                           14/18 
  运行脚本: glibc-all-langpacks-2.28-197.el8.x86_64                                                                           14/18 
  清理    : glibc-langpack-en-2.28-197.el8.x86_64                                                                             15/18 
  清理    : glibc-common-2.28-197.el8.x86_64                                                                                  16/18 
  清理    : glibc-langpack-zh-2.28-197.el8.x86_64                                                                             17/18 
  清理    : glibc-2.28-197.el8.x86_64                                                                                         18/18 
  运行脚本: glibc-all-langpacks-2.28-216.el8.x86_64                                                                           18/18 
  运行脚本: glibc-2.28-197.el8.x86_64                                                                                         18/18 
  运行脚本: glibc-common-2.28-216.el8.x86_64                                                                                  18/18 
  验证    : glibc-static-2.28-216.el8.x86_64                                                                                   1/18 
  验证    : libxcrypt-static-4.1.1-6.el8.x86_64                                                                                2/18 
  验证    : glibc-2.28-216.el8.x86_64                                                                                          3/18 
  验证    : glibc-2.28-197.el8.x86_64                                                                                          4/18 
  验证    : glibc-all-langpacks-2.28-216.el8.x86_64                                                                            5/18 
  验证    : glibc-all-langpacks-2.28-197.el8.x86_64                                                                            6/18 
  验证    : glibc-common-2.28-216.el8.x86_64                                                                                   7/18 
  验证    : glibc-common-2.28-197.el8.x86_64                                                                                   8/18 
  验证    : glibc-devel-2.28-216.el8.x86_64                                                                                    9/18 
  验证    : glibc-devel-2.28-197.el8.x86_64                                                                                   10/18 
  验证    : glibc-gconv-extra-2.28-216.el8.x86_64                                                                             11/18 
  验证    : glibc-gconv-extra-2.28-197.el8.x86_64                                                                             12/18 
  验证    : glibc-headers-2.28-216.el8.x86_64                                                                                 13/18 
  验证    : glibc-headers-2.28-197.el8.x86_64                                                                                 14/18 
  验证    : glibc-langpack-en-2.28-216.el8.x86_64                                                                             15/18 
  验证    : glibc-langpack-en-2.28-197.el8.x86_64                                                                             16/18 
  验证    : glibc-langpack-zh-2.28-216.el8.x86_64                                                                             17/18 
  验证    : glibc-langpack-zh-2.28-197.el8.x86_64                                                                             18/18 

已升级:
  glibc-2.28-216.el8.x86_64                   glibc-all-langpacks-2.28-216.el8.x86_64       glibc-common-2.28-216.el8.x86_64       
  glibc-devel-2.28-216.el8.x86_64             glibc-gconv-extra-2.28-216.el8.x86_64         glibc-headers-2.28-216.el8.x86_64      
  glibc-langpack-en-2.28-216.el8.x86_64       glibc-langpack-zh-2.28-216.el8.x86_64        
已安装:
  glibc-static-2.28-216.el8.x86_64                                libxcrypt-static-4.1.1-6.el8.x86_64                               

完毕!
[root@bogon pro]# dnf --enablerepo=powertools install libstdc++-static
上次元数据过期检查:0:16:26 前,执行于 2022年11月17日 星期四 08时28分45秒。
依赖关系解决。
==========================================================================================================================================================================================
 软件包                                           架构                                   版本                                            仓库                                        大小
==========================================================================================================================================================================================
安装:
 libstdc++-static                                 x86_64                                 8.5.0-17.el8                                    powertools                                 600 k

事务概要
==========================================================================================================================================================================================
安装  1 软件包

总下载:600 k
安装大小:5.1 M
确定吗?[y/N]: y
下载软件包:
libstdc++-static-8.5.0-17.el8.x86_64.rpm                                                                                                                  2.8 MB/s | 600 kB     00:00    
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
总计                                                                                                                                                      1.0 MB/s | 600 kB     00:00     
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
  准备中  :                                                                                                                                                                           1/1 
  安装    : libstdc++-static-8.5.0-17.el8.x86_64                                                                                                                                      1/1 
  运行脚本: libstdc++-static-8.5.0-17.el8.x86_64                                                                                                                                      1/1 
  验证    : libstdc++-static-8.5.0-17.el8.x86_64                                                                                                                                      1/1 

已安装:
  libstdc++-static-8.5.0-17.el8.x86_64                                                                                                                                                    

完毕!
[root@bogon pro]# g++ test.cpp -o a -static
[root@bogon pro]# 
[root@localhost ~]# yum install --enablerepo powertools​ libstdc++-static -y
上次元数据过期检查:0:17:45 前,执行于 2022年11月17日 星期四 23时44分48秒。
依赖关系解决。
====================================================================================================================================
 软件包                              架构                      版本                             仓库                           大小
====================================================================================================================================
安装:
 libstdc++-static                    x86_64                    8.5.0-17.el8                     powertools                    600 k

事务概要
====================================================================================================================================
安装  1 软件包

总下载:600 k
安装大小:5.1 M
下载软件包:
[MIRROR] libstdc++-static-8.5.0-17.el8.x86_64.rpm: Curl error (18): Transferred a partial file for http://mirrors.njupt.edu.cn/centos/8-stream/PowerTools/x86_64/os/Packages/libstdc%2b%2b-static-8.5.0-17.el8.x86_64.rpm [transfer closed with 387698 bytes remaining to read]
libstdc++-static-8.5.0-17.el8.x86_64.rpm                                                             19 kB/s | 600 kB     00:31    
------------------------------------------------------------------------------------------------------------------------------------
总计                                                                                                 19 kB/s | 600 kB     00:31     
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
  准备中  :                                                                                                                     1/1 
  安装    : libstdc++-static-8.5.0-17.el8.x86_64                                                                                1/1 
  运行脚本: libstdc++-static-8.5.0-17.el8.x86_64                                                                                1/1 
  验证    : libstdc++-static-8.5.0-17.el8.x86_64                                                                                1/1 

已安装:
  libstdc++-static-8.5.0-17.el8.x86_64                                                                                              

完毕!
[root@localhost ~]# 

        然后再静态编译试试:

[root@localhost ~]# gcc pighello.c -o pighello -static
[root@localhost ~]# g++ pighello.cpp -o pighello -static
[root@localhost ~]# 

         重新构建镜像并执行:

[root@localhost ~]# mv pighello ./package/
[root@localhost ~]# cd package/
[root@localhost package]# ls
Dockerfile  pighello
[root@localhost package]# docker build -t pig:1 .
Sending build context to Docker daemon  3.428MB
Step 1/3 : FROM scratch
 ---> 
Step 2/3 : COPY pighello /
 ---> a291200e3be6
Step 3/3 : CMD ["/pighello"]
 ---> Running in 7ac260b798a3
Removing intermediate container 7ac260b798a3
 ---> ee3adaaf3c7a
Successfully built ee3adaaf3c7a
Successfully tagged pig:1
[root@localhost package]# docker run pig:1
test docker and print hello
[root@localhost package]# 

        如此就顺利地搞定了。

        4.直接打包文件系统构建镜像

        其实前面我们提到,container的export方法只不过是把容器快照当时的文件系统给打包导出了,然后从镜像装在容器只是再用image的import导入后重新挂上内核运行时而已。从这个原理角度,我们完全可以自行手工剪裁系统并打包文件,然后构建镜像。

        当然,篇幅原因。另外我打算用这个方法干一件蠢事,所以留待下篇再说……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/15993.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]SSM计算机毕业设计中小企业人事管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

[附源码]Python计算机毕业设计安庆师范大学校园互助平台

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

C语言学习记录(十二)之字符串和字符串函数

文章目录一、字符串和字符串I/O1.1 定义字符串1.1.1 字符串字面量(字符串常量)1.1.2 字符串数组和初始化1.1.3 数组和指针1.1.4 数组和指针的区别二、字符串输入2.1 分配空间2.2 gets()函数 (不建议使用)2.3 gets()的替代品2.3.1 fgets()函数(和fputs())2.3.2 gets_s()函数2.3.…

【推荐算法毕业设计源码】个性化学习推荐网站的设计及实现丨可定制

登录该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等学习内容。 目录 一、项目介绍&#xff1a; 二、文档学习资料&#xff1a; 三、模块截图&#xff1a; 四、开发技术与运行环境&#xff1a; 五、代码展示&#xff1a; 六、数据库表截图&#x…

UE4 GIS Cesium for Unreal插件的使用 教程

效果&#xff1a;&#xff08;成都郫都区某区域的运行场景&#xff09; 步骤&#xff1a; 1.到虚幻商城搜索 cesiuml&#xff0c;点击Cesium for Unreal 打开后可以看到目前支持的版本有4.26-4.27和5.0 将其安装到引擎 大概0.2G 2.下载完成后&#xff0c;打开4.26版本的虚幻编…

Study Git - Shell command with Git

前言 这一部分内容主要记录git使用时的重要命令&#xff0c;文章参考&#xff1a; MIT Missing classGit Pro Basic git help \<command>: get help for a git commandgit init: creates a new git repo, with data stored in the .git directorygit status: tells yo…

pytest学习和使用9-fixture中conftest.py如何使用?

9-fixture中conftest.py如何使用&#xff1f;1 引入2 conftest.py简介3 conftest.py特点4 实例4.1 conftest.py4.2 test_conftest1.py4.3 test_conftest2.py5 conftest.py优先级1 引入 之前学习使用fixture前置实现用例的登陆&#xff0c;当时在一个脚本中实现的&#xff1b;那…

基于PHP+MySQL学生创新作品展示系统的设计与实现

MySQL学生创新作品展示系统的基本功能包括用户注册登录,发布作品,查看作品和对评论评论以及在线留言等信息。 PHP本科学生创新作品展示系统是一个服务类型的网站,系统通过PHp&#xff1a;MySQL进行开发,分为前台和后台两部分,前台部分主要是让大学生查看和发布创新作品使用的。…

N3-PEG-MAL,Azdio-PEG-Maleimide,一种点击化学PEG试剂

击化学PEG试剂叠氮-聚乙二醇-马来酰亚胺&#xff0c;该化学试剂其英文名为Azdio-PEG-Maleimide&#xff0c;&#xff08;N3-PEG-MAL&#xff09;。所属分类为&#xff1a;Azide PEG Maleimide PEG。 化学试剂叠氮-PEG-马来酰亚胺的分子量均可定制&#xff0c;有&#xff1a;N3…

音视频开发面试题集锦

下面是 2022.06 月音视频面试题集锦内容的节选&#xff1a; 一、如何根据 NALU 裸流数据来判断其是 H.264 编码还是 H.265 编码&#xff1f; 1&#xff09;通常我们不是根据 NALU 裸流数据中的信息来选择解码器&#xff0c;而是根据媒体封装层的信息来确定解码器。 媒体封装层…

理解TCP协议三次握手、四次挥手、流量控制、拥塞控制 、重传机制

&#x1f468;‍&#x1f4bb;个人主页&#xff1a; 才疏学浅的木子 &#x1f647;‍♂️ 本人也在学习阶段如若发现问题&#xff0c;请告知非常感谢 &#x1f647;‍♂️ &#x1f4d2; 本文来自专栏&#xff1a; 计算机网络 &#x1f308; 每日一语&#xff1a;真正的勇气是&…

Mac 常用软件汇总

开发工具 1、Android Studio Android开发工程师对这个玩意是又爱又狠&#xff0c;爱它的灵活自由&#xff0c;恨他的放纵不羁。 2、Sourcetree git 图形化操作工具。 3、IntelliJ IDEA 开发Java项目神器。 4、Serial 串口调试工具。可以打印一些日志信息。 5、Navicat …

Python与pycharm-----windows安装与运行

目录 1.python下载 2.Python安装 3、安装并配置pycharm 1.python下载 上python官网下载。很多计算机自带python&#xff0c;如果不自带的话&#xff0c;需要官网下载。 选好版本&#xff0c;最好为3.7版本的。 2.Python安装 需要记下安装路径&#xff0c;免得后续找不到&am…

【算法系列】非线性最小二乘求解-梯度下降法

系列文章目录 【算法系列】卡尔曼滤波算法 【算法系列】非线性最小二乘求解-直接求解法 【算法系列】非线性最小二乘求解-梯度下降法 【算法系列】非线性最小二乘-高斯牛顿法 文章目录 系列文章 文章目录 前言 一、梯度下降法&#xff08;GD&#xff09; 二、最速下…

深度优先与宽度优先搜索(python)

算法原理 1、宽度优先搜索&#xff1a; 宽度优先搜索算法(Breadth First Search&#xff0c;BSF)&#xff0c;思想是&#xff1a; 从图中某顶点v出发&#xff0c;首先访问顶点v在访问了v之后依次从左往右访问v的各个未曾访问过的邻接点&#xff1b;然后分别从这些邻接点出发依…

loT行业生死竞速:Aqara绿米得用户得天下

作者 | 曾响铃 文 | 响铃说 日前&#xff0c;社科院发布了一份“2022年秋季中国宏观经济形势分析”报告&#xff0c;报告中指出当前&#xff0c;世界经济增长预期下挫&#xff0c;全球通胀居高不下&#xff0c;而中国经济整体仍呈持续恢复状态&#xff0c;但经济内增长动能仍…

【数据结构】树和二叉树以及经典例题

目录1.树的基本概念1.1 树的特点1.2 树的一些相关概念1.3 树的表示1.3.1 那种结构表示树最优&#xff1f;&#xff08;不是二叉树&#xff0c;就是普通的树&#xff09;1.4 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09;2. 二叉树&#xff08;重点&#x…

嵌入式linux实现pppoe拨号上网

make menuconfig -> Device Drivers -> Network device support -> PPP (point-to-point protocol) 中&#xff0c;选中所有ppp选项。退出&#xff0c;保存配置&#xff0c;修改Makefile重新执行make zImage. 将arch/mips/boot/下的zImage下载到开发板上重启系统。 t…

oracle数据库的导入与导出

1、oracle数据库导入与导出需要注意 2、导出数据格式介绍 3、 传统方式exp(导出&#xff09;和&#xff08;imp&#xff09;导入 3.1 命令执行方式 3.2 命令格式 3.3 导出数据 3.3.1示例 3.4 导入数据 3.4.1 导入数据 4 使用PL/SQL Developer 实现数据导入与导出 4.1 导出与导…

文本分类微调技巧实战2.0

讯飞比赛答辩结束&#xff0c;笔者和小伙伴们参加了一些讯飞的比赛&#xff0c;今年讯飞文本分类比赛相比去年更加多元化&#xff0c;涉及领域、任务和数据呈现多样性&#xff0c;听完各位大佬的答辩之后&#xff0c;结合之前经验和以下赛题总结下文本分类比赛的实战思路。 1 …