Ubuntu上安装使用Docker

Docker简介

  • Docker是一个开源的容器引擎,他有助于更快的交付应用。Docker可以将应用程序和基础设施层做隔离,并且能将基础设施当做程序一样进行管理。使用Docker,可以更快的打包,测试以及部署应用程序,并且可以缩短从编写到部署运行的代码调试周期。
    Docker官网
    Docker 的GitHub

Docker 的架构

  • 以下是Docker官方文档的架构图
    在这里插入图片描述
  • Docker daemon(Docker守护进程):Docker daemon是一个运行在宿主机(DOCKER_HOST)的后台进程。可以通过Docker客户端与Docker daemon进行通信
  • Client (Docker 客户端): Docker客户端是Docker的用户界面,他可以接受用户命令和配置标识,并与Docker daemon通信。途中,Docker build 等都是Docker的相关命令
  • Images(Docker 的镜像):Docker镜像是一个只读的模板,他包含创建Docker容器的说明。他和系统安装光盘有点像----使用系统安装光盘可以安装系统,同理,使用Docker镜像可以运行Docker镜像中的程序。
  • Container(容器):容器是镜像的可运行实例。镜像和容器的关系有点类似面向对象中的,类之于对象的关系。可通过Docker API或者CLI命令来启动停止,移动,删除容器。
  • Registry(类似代码仓库):Docker Registry是一个集中存储于分发镜像的服务。构建完Docker镜像后,就可以在当前宿主机上运行。如果想在其他机器上运行这个镜像,需要手动负责,或者借助Docker Registry来避免负责,经Docker镜像push到Docker Registry上,然后在其他机器上pull对应镜像。

Docker安装

  • 准备Ubuntu系统,或者虚拟机,安装程序可参照网址
安装Docker
  • 官方Ubuntu存储库中提供的Docker安装包,但是可能不是最新的版本,为了确保获取最新版,我们将从Docker官网存储库安装Docker。因此,我们需要添加一个新的资源包,从Docker添加GPG以确保下载有效,然后安装该包:
  • 首先更新现有包列表,新安装的ubuntu这个步骤可能会久一点:
sudo apt update
  • 接下来使用按apt 安装一下运行通过HTTPS才能使用的软件包
sudo apt install apt-transport-https 
sudo apt install ca-certificates 
sudo apt install curl 
sudo apt install software-properties-common
  • 将官方Docker存储的GPG秘钥添加到系统:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  • 将Docker存储库添加到APT源:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
  • 接下来,使用新添加的repo源中的Docker包更新数据库:
sudo apt update
  • 确保从Docker repo安装,而不是默认的Ubuntu repo:
apt-cache policy docker-ce
  • 看到如下的输出,说明是成功的,版本不同输出的日志应该有一点点差异:
docker-ce:Installed: (none)Candidate: 5:19.03.12~3-0~ubuntu-bionicVersion table:5:19.03.12~3-0~ubuntu-bionic 500500 https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
  • 现在Docker-ce还没有安装,用上面这个命令我们能看到安装源来自Docker官方存储库,最后安装Docker:
sudo apt install docker-ce
  • 现在Docker已经安装好了,检查一下是否正常运行:
sudo systemctl status docker
  • 有类似如下的输出,标准状态正常:
● docker.service - Docker Application Container EngineLoaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: eActive: active (running) since Tue 2020-07-21 00:07:42 PDT; 34s agoDocs: https://docs.docker.comMain PID: 20120 (dockerd)Tasks: 8CGroup: /system.slice/docker.service└─20120 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/contai
  • Docker不仅仅提供Docker服务,还提供了Docker命令行工具或者Docker客户端。
非Sudo执行Docker命令
  • 默认情况下,Docker命令只能Root用户或者Docker组中用户运行,改用户在Docker安装过程中自动创建,如果想要不使用Sudo运行,或不在docker组中的用户运行会有错误提示信息:
docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
See 'docker run --help'.
  • 想要在运行docer时候不输入sudo,需要将用户添加到docker组中,首先创建docker用户组
sudo groupadd docker
  • 将用户添加到docker用户组
sudo usermod -aG docker ${USER_NAME}
  • 重启docker服务
sudo systemctl restart docker
使用Docker命令
  • 以下我都用的root用户来执行,Docker命令使用包括传递一系列docker选项和命令,后跟参数。语法格式如下:
docker [option] [command] [arguments]
  • 查询所有子命令输入 docker,有如下:
Commands:attach      Attach local standard input, output, and error streams to a running containerbuild       Build an image from a Dockerfilecommit      Create a new image from a container's changescp          Copy files/folders between a container and the local filesystemcreate      Create a new containerdiff        Inspect changes to files or directories on a container's filesystemevents      Get real time events from the serverexec        Run a command in a running containerexport      Export a container's filesystem as a tar archivehistory     Show the history of an imageimages      List imagesimport      Import the contents from a tarball to create a filesystem imageinfo        Display system-wide informationinspect     Return low-level information on Docker objectskill        Kill one or more running containersload        Load an image from a tar archive or STDINlogin       Log in to a Docker registrylogout      Log out from a Docker registrylogs        Fetch the logs of a containerpause       Pause all processes within one or more containersport        List port mappings or a specific mapping for the containerps          List containerspull        Pull an image or a repository from a registrypush        Push an image or a repository to a registryrename      Rename a containerrestart     Restart one or more containersrm          Remove one or more containersrmi         Remove one or more imagesrun         Run a command in a new containersave        Save one or more images to a tar archive (streamed to STDOUT by default)search      Search the Docker Hub for imagesstart       Start one or more stopped containersstats       Display a live stream of container(s) resource usage statisticsstop        Stop one or more running containerstag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGEtop         Display the running processes of a containerunpause     Unpause all processes within one or more containersupdate      Update configuration of one or more containersversion     Show the Docker version informationwait        Block until one or more containers stop, then print their exit codes
  • 查看有关Docker的系统信息:
docker info
  • 搜索镜像:
socker search java
  • 执行后可以看到如下表格信息
NAME                                     DESCRIPTION                                     STARS               OFFICIAL      AUTOMATED
node                                     Node.js is a JavaScript-based platform for s…   9044                [OK]                
tomcat                                   Apache Tomcat is an open source implementati…   2785                [OK]                
openjdk                                  OpenJDK is an open-source implementation of …   2347                [OK]                
java                                     Java is a concurrent, class-based, and objec…   1976                [OK]                
ghost                                    Ghost is a free and open source blogging pla…   1221                [OK]                
couchdb                                  CouchDB is a database that uses JSON for doc…   358                 [OK]                
jetty                                    Jetty provides a Web server and javax.servle…   340                 [OK]                
groovy                                   Apache Groovy is a multi-faceted language fo…   97                  [OK]                
lwieske/java-8                           Oracle Java 8 Container - Full + Slim - Base…   46                                      [OK]
nimmis/java-centos                       This is docker images of CentOS 7 with diffe…   42                                      [OK]
fabric8/java-jboss-openjdk8-jdk          Fabric8 Java Base Image (JBoss, OpenJDK 8)      28                                      [OK]
frekele/java                             docker run --rm --name java frekele/java        12                                      [OK]
fabric8/java-centos-openjdk8-jdk         Fabric8 Java Base Image (CentOS, OpenJDK 8,11                                      [OK]
blacklabelops/java                       Java Base Images.                               8                                       [OK]
..............
  • 以上表格中五列含义如下:

    • NAME:镜像仓库名称
    • DESCRIPTION:镜像仓库描述
    • STARS:镜像仓库收藏数量,标识该镜像受欢迎程度,类似GitHub的Stars
    • OFFICAL:表示是否为官方仓库,改列标记为[OK] 的镜像都是各软件官方项目组创建和维护的。由结果可知,frekele/java 这个镜像不是官方仓库。
    • AUTOMATED:表示是否是自动构建的镜像仓库
  • 下载镜像

    • 使用 docker pull 命令可以从Docker Registry上下载镜像,例如:docker pull java
    • 命令执行后,Docker会从Docker Hub上的java残酷中下载最新版本的java镜像。若镜像下载缓慢可以配置加速器(以下会讲解加速器配置)
  • 列出已有镜像,使用docker images命令可以列出已经下载的镜像。执行后有如下表格:

REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ubuntu               latest              adafef2e596e        2 weeks ago         73.9MB
645121107/ljmadmin   myHelloWorld        bf756fb1ae65        6 months ago        13.3kB
hello-world          latest              bf756fb1ae65        6 months ago        13.3kB
  • 包括五列,分别有如下意义:
    • REPOSITORY:镜像所属的仓库名称
    • TAG:镜像标签,默认是lastest,表示最新
    • IMAGE ID:镜像ID,表示镜像唯一标识
    • CREATED:镜像创建时间
    • SIZE:镜像大小
  • 删除镜像:
docker rmi hello-world
  • 删除镜像可能遇到如下问题,原因是提示有关联的Docker容器,因为我们看到bf756fb1ae65 对应了两个容器,一个是我们自己提交的tag,通过hello-world生成的一个镜像,系统无法识别你要删除的是哪一个:
root@ljmadmin-virtual-machine:/home/ljmadmin# docker rmi bf756fb1ae65
Error response from daemon: conflict: unable to delete bf756fb1ae65 (must be forced) - image is referenced in multiple repositories
  • 我们删除的时候可以用指定repository和tag的方式来删除,比如:
root@ljmadmin-virtual-machine:/home/ljmadmin# docker rmi hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:49a1c8800c94df04e9658809b006fd8a686cab8028d33cfba2cc049724254202
  • 如上,线上已经被删除成功
批量删除镜像
  • 删除所有:
docker rm `docker ps -a -q`
  • 删除所有镜像
docker rmi `docker images -q`
  • 按条件删除镜像
//没有标签情况
docker rmi `docker images -q | awk '/^<none>/ {pring $3}'`
//镜像名包含关键字
docker rmi --force `docker images | grep eureka | awk '{print $3}'`    //其中eureka为关键字
Docker 容器常用命令
  • 新建并启动容器:使用docker run 命令可以新建并启动一个容器。该命令是常用命令,他有很多选项,下面列举某一些选项:
    • -d选项:表示后台运行
    • -p选项:随机端口映射
    • -p选项:指定端扣映射,有以下四种格式:
      • ip:hostPort:containerPort
      • ip::containerPort
      • hostPort:containerPort
      • containerPort
    • –network选项: 指定网络模式,该选项有以下可选参数:
      • –network=bridge:默认选项,表示连接到默认的网桥
      • –network=host:容器使用宿主机网络
      • –network=container:NAME_or_ID:告诉Docker让新建的容器使用已有容器的网络配置。
      • –network=none:不配置该容器网络,用户可以自定义网络配置
  • 示例一,这样终端会打印Hello world,跟在本地执行/bin/echo ‘Hello world’ 得到一样的结果:
docker run java /bin/echo 'Hello world'
  • 示例二,启动一个Nginx容器,这里添加了两个参数,含义与命令如下所示:
docker run -d -p 91:80 nginx //没有nginx镜像时候,会先下载在启动
// -d 表示后台运行
//-p 宿主机端口:容器端口  # 开放容器端口到宿主机端口
  • 访问http://Docker宿主机IP:91,将会看到如下界面
    在这里插入图片描述

  • 进入容器,某些场景下需要进入容器中。

    • 使用docker sttach命令进入容器,弊端在于,使用此命令并不方便,当多个窗口同事attach到同一个容器时候,所有窗口都会同步显示。同样,当某个窗口发生阻塞,其他窗口也无法执行操作。命令如下
    • 使用nsenter进入容器:nsenter工具包含在util-linux2.23或者更高版本中。为了连接到容器,需要找到容器第一个进程PID,可以以下命令获取
    • 以上获取到PID后,就可以使用nsenter进入容器,完整命令如下
docker  attach b8488a2dcef8
docker inspect --format "{{.State.Pid}}" $CONTAINER_ID
nsenter --target "$PID" --mount --uts --ipc --net --pid
- 完整案例如下图:

在这里插入图片描述

配置镜像加速器
  • 国内访问Docker Hub的速度很不稳定,有时候会出现链接不上的情况。我们可以通过配置国内镜像加速器的形式来解决问题。目前,国内很多公司云服务商提供了镜像加速服务。常用镜像加速器有:阿里云加速器,DaoCloud加速器。我用的阿里云的加速器,配置如下:
  1. 注册阿里云账号,登录控制台(https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors),如下图
    在这里插入图片描述
  2. 按上图所示进行配置即可。
使用Docker镜像
  • Docker容器是从Docker进行构建的,默认情况下,Docker从Docker Hub中pull下来的这些镜像,这是一个由Docker管理的Docker镜像市场,这是Docker项目背后的公司。任何人都可以在Docker Hub上托管他们的Docker镜像,所以你只要将你的应用程序和LInux放再那边托管就可以。
  • 我们用刚才pull的hello-world镜像测试,输入:
docker run hello-world
  • 输出下面的内容说明已经成功运行
Hello from Docker!
This message shows that your installation appears to be working correctly.To generate this message, Docker took the following steps:1. The Docker client contacted the Docker daemon.2. The Docker daemon pulled the "hello-world" image from the Docker Hub.(amd64)3. The Docker daemon created a new container from that image which runs theexecutable that produces the output you are currently reading.4. The Docker daemon streamed that output to the Docker client, which sent itto your terminal.
..................
运行Docker容器
  • 上一步中,hello-world容器运行并发出一个测试消息后退出容器,容器可以比这更有用,是可以相互交互的,比较,类似虚拟机,只是更加有利于资源。
  • 我们用ubuntu的镜像做一个测试,通过-i, -t子命令提供了容器的交互shell访问:
docker pull ubuntu
docker run -it ubuntu
  • 执行以上两个命令就可以进入到ubuntu镜像内部,shell展示如下
root@ljmadmin-virtual-machine:/home/ljmadmin# docker run -it ubuntu 
root@b8488a2dcef8:/# 
  • 如上命令提示符中的容器ID,在此处是b8488a2dcef8,在此shell中不需要sudo,因为是用root用户身份在容器中操作,我们在此镜像中安装一个node:
apt update
apt install nodejs
node -v
  • 得到如下结果:
root@b8488a2dcef8:/# node -v
v10.19.0
  • 退出容器,直接输入exit或者Ctrl+d 退出,两种方式有如下区别
    • 对于创建的bash容器,当使用exit命令退出后,容器就自动处于退出(Exited)状态,这是因为对Docker容器来说,当运行的应用退出后,容器就没有继续运行的必要
    • 而用Ctrl退出后,容器还会在运行,他认为你只是退出了命令界面的链接状态而已
Docker容器管理
  • 使用Docker后,可能有很多非运行状态的容器,我们需要查询容器的运行状态用如下命令:
docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
b8488a2dcef8        ubuntu              "/bin/bash"         6 minutes ago       Up 6 minutes                            adoring_knuth
  • 看到如上输出,每一列的含义如下:

    • CONTAINER_ID:表示容器ID
    • IMAGE:表示镜像名称
    • COMMAND:表示启动容器时运行的命令
    • CREATED:表示容器创建时间
    • STATUS:容器运行状态,Up标识运行中,Exited表示停止
    • PORTS:容器对外的端口号
    • NAMES:表示容器名称,默认由Docker自动生成,也可以docker run 命令后面–name自行指定。
  • 查看所有容器情况使用 docker ps -a,得到所有的信息,如下:

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
b8488a2dcef8        ubuntu              "/bin/bash"         15 minutes ago      Up 15 minutes                                   adoring_knuth
43971aec0ea0        hello-world         "/hello"            26 minutes ago      Exited (0) 26 minutes ago                       dazzling_hodgkin
  • 只查看已经启动的容器:
docker ps
  • 启动已经停止的容器,使用Docker start ,后面跟上容器ID b8488a2dcef8 ,启动后status会变为up状态
  • 同样,停止容器,使用docker stop CONTAINER_ID,更容器id或者容器名称
  • 批量停止容器 docker stop 51c20c4f5a04 22c37049f352 1ac1218c1a54
  • 删除容器,当我们不需要某个容器时候,可以docker rm删除,上面内容以及讲过这个命令。
将容器中的更改提交给Docker镜像
  • 当启动Docker镜像后,可以像虚拟机一样创建,修改,删除文件。例如ubuntu镜像,我们所有更改都仅仅在镜像内部而已。我们可以通过docker rm销毁,但是会永久丢失。
  • 在ubuntu容器中安装Nodejs后,我们现在想要将这个容器作为一个新的容器,可以如下操作:
docker ps -a //找到对应ubuntu镜像id
docker commit -m "my ubuntu" -a "ljmadmin" b8488a2dcef8 ljmadmin/ubuntu-nodejs 
  • 如上commit命令,对于ljmadmin用户,使用容器id b8488a2dcef8 作为目标镜像,打包成新镜像 ljmadmin/ubuntu-nodejs ,得到如下所有images信息:
root@ljmadmin-virtual-machine:/home/ljmadmin# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED              SIZE
ljmadmin/ubuntu-nodejs   latest              6e1bc5c5a996        About a minute ago   163MB
ubuntu                   latest              adafef2e596e        2 weeks ago          73.9MB
645121107/ljmadmin       myHelloWorld        bf756fb1ae65        6 months ago         13.3kB
hello-world              latest              bf756fb1ae65        6 months ago         13.3kB
  • 在如上列表中新镜像ubuntu-nodejs 是动Docker Hub的Ubuntu现有镜像中衍生出来的,镜像大小的差异可以看出有变化因此下次我们可以直接使用ubuntu-nodejs 新的镜像。
Dockerfile构建镜像
  • 待续
将Docker镜像推送到Docker存储库
  • 我们以上提到的从Docker Hub pull下来的镜像都是在我们本地,包括我们自己commit生成的也是在本地,如果需要迁移需要先将镜像推到远程仓库,我们需要 一个Docker Hub的仓库账号信息
docker login -u docker-registry-username //docker-registry-username 标识你注册docker Hub的用户名
  • 系统将提升输入Docker Hub的密码进行身份验证,然后你可以使用以下方法推送自己的镜像:
  • 第一步:获取需要推送到远端镜像的 容器ID(CONTAINER ID),此处我们用ubuntu来进行测试提交,ID是b8488a2dcef8,如下命令:
root@ljmadmin-virtual-machine:/home/ljmadmin# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS               NAMES
b8488a2dcef8        ubuntu              "/bin/bash"         3 hours ago         Exited (0) 3 hours ago                       adoring_knuth
43971aec0ea0        hello-world         "/hello"            4 hours ago         Exited (0) 4 hours ago                       dazzling_hodgkin
  • 第二步将对应Docker容器打包成镜像:
root@ljmadmin-virtual-machine:/home/ljmadmin# docker commit -m "my first ubuntu" -a "ljmadmin" b8488a2dcef8 ljmadmin/ubuntu-nodejs
sha256:acd28a5810ec9e3ecd656fcaf58551552804f7a5663e3c201a1d3d7712621120
  • 第三步Docker Images 命令查询打包好的镜像文件,并且获取对应镜像ID:
root@ljmadmin-virtual-machine:/home/ljmadmin# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
ljmadmin/ubuntu-nodejs   latest              acd28a5810ec        20 seconds ago      163MB
ubuntu                   latest              adafef2e596e        2 weeks ago         73.9MB
hello-world              latest              bf756fb1ae65        6 months ago        13.3kB
  • 第四部:将需要提交的镜像文件通过docker tag命令打包成自己仓库对应的镜像文件(之前的镜像默认是Docker hub公共的仓库)
root@ljmadmin-virtual-machine:/home/ljmadmin# docker tag acd28a5810ec 645121107/ljmadmin
root@ljmadmin-virtual-machine:/home/ljmadmin# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
645121107/ljmadmin       latest              acd28a5810ec        15 minutes ago      163MB
ljmadmin/ubuntu-nodejs   latest              acd28a5810ec        15 minutes ago      163MB
ubuntu                   latest              adafef2e596e        2 weeks ago         73.9MB
645121107/ljmadmin       myHelloWorld        bf756fb1ae65        6 months ago        13.3kB
hello-world              latest              bf756fb1ae65        6 months ago        13.3kB
  • 此处没有指定tag的名称,如需指定名称用以下命令:
docker tag acd28a5810ec 645121107/ljmadmin:yourTagName
  • 如上images命令后可以看的多了一个仓库名称(REPOSITORY)是645121107/ljmadmin的镜像文件,并且该镜像文件的id和我们之前通过tag打包成镜像的id是同一个,说明他们是同一个文件,我们可以理解为将他的副本映射到了我们自己的仓库地址,以下是我创建的仓库
    在这里插入图片描述

  • 第五步提交对应镜像文件,通过docker push命令提交

root@ljmadmin-virtual-machine:/home/ljmadmin# docker push 645121107/ljmadmin
  • 执行以上命令后会得到如下的输出,因为文件有十几M甚至100M,所以需要一定时间,以上命令和git push类似,645121107/ljmadmin 其实就是远程仓库地址,如果ljmadmin 是别在包例如645121107/1234,docker hub也会自动在远程仓库创建新的文件1234.
    在这里插入图片描述
  • 在仓库中可以看到刚才提交的文件如下:
    在这里插入图片描述
  • 第六部:验证提交的镜像文件有效
docker rmi docker rmi 645121107/ljmadmin:latest //通过rmi命令删除本地对应的镜像文件
root@ljmadmin-virtual-machine:/home/ljmadmin# docker images  //查看现有镜像文件
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ubuntu               latest              adafef2e596e        2 weeks ago         73.9MB
root@ljmadmin-virtual-machine:/home/ljmadmin# docker pull 645121107/ljmadmin:latest
  • 如下图所示,说明以及在下载文件:
    在这里插入图片描述
查看Docker容器启动日志
  • 用的最多的一个,实时日志跟踪,类似 tail -f -n 300 xxx.log
sudo docker logs -f -t --tail 行数 容器名
//docker logs [OPTIONS] CONTAINER
//sudo docker logs -f -t 300 CONTAINER_ID
  • Options操作如下:

    • –details 显示更多信息
    • -f, --follow 跟踪实时日志信息
    • –since string 显示自某个timestamp之后的日志,或相对时间,如40m(40分钟)
    • -tail string 从日志末尾开始算显示多少行日志,默认是all
    • -t, --timestamp 显示时间搓
    • –until string 显示自某个timestamp之前的日志信息,或者相对时间,如40m(40分钟)
  • 查看最近30分钟的日志:

docker logs --since 30m CONTAINER_ID
  • 查看某时间之后的日志:
docker logs -f --since = "2020-08-26T13:23:37" CONTAINER_ID
  • 查看某时间段日志:
docker logs -t --since= "2020-08-25T13:23:37" --until  "2020-08-26T13:23:37" CONTAINER_ID

下一篇 SpringCloud + Docker

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

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

相关文章

让 .NET 轻松构建中间件模式代码

让 .NET 轻松构建中间件模式代码Intro在 asp.net core 中中间件的设计令人叹为观止&#xff0c;如此高大上的设计何不集成到自己的代码里呢。于是就有了封装了一个简单通用的中间件模板的想法&#xff0c;以后有需要的时候就可以拿来即用。接口定义这里按执行的委托是同步还是异…

[剑指offer]面试题26:复杂链表的复制

面试题26&#xff1a;复杂链表的复制 题目&#xff1a;请实现函数ComplexListNodeClone&#xff08;ComplexListNodepHead&#xff09;&#xff0c;复制一个复杂链表。在复杂链表中&#xff0c;每个结点除了有一个m_pNext指针指向下一个结点外&#xff0c;还有一个m_pSibling 指…

SpringCloud + Docker

Dockerfile构建Docker 镜像 注意这里说的Dockerfile是指的一个文本文件&#xff0c;类似txt&#xff0c;只不过名字是Dockerfile&#xff0c;里面编辑Docker的一些指令&#xff0c;指令作用在于描述构建镜像的细节。如下一个简单的案例&#xff0c;用上一节中下载的nginx镜像来…

红帽借“订阅”模式成开源一哥,首创者升任总裁

4 月 6 日&#xff0c;红帽公司宣布&#xff0c;产品和技术总裁 Paul Cormier 即日起任红帽总裁&#xff0c;并兼任首席执行官。Paul Cormier 是开源商业化“订阅”模式的提出者&#xff0c;这一模式促使红帽达成连续超70个季度的盈利&#xff0c;身价升至340亿美金&#xff0c…

Docker中数据管理

Docker数据管理 生产环境中&#xff0c;对数据进行持久化&#xff0c;或者需要在多个容器直接进行数据共享&#xff0c;这必然涉及到容器的一些数据管理的操作。容器中数据管理主要有两种方式&#xff1a; 数据卷&#xff08;Data Volumes&#xff09;&#xff1a;容器内数据直…

C#两大知名Redis客户端连接哨兵集群的姿势

前言前面《Docker-Compose搭建Redis高可用哨兵集群》&#xff0c;我的思路是将Redis、Sentinel、Redis Client App链接到同一个网桥网络&#xff0c;这个网桥内的Redis Client App就可以使用ContainerIP访问网桥内任意redis节点。同一网桥网络访问规避了Docker上发生的NAT&…

Docker之Dockerfile详解

使用Dockerfile创建镜像 Dockerfile是一个文本格式的配置文件&#xff0c;我们可以利用Dockerfile来快速的创建一个自定义的镜像。 基本结构 Dockerfile由一行命令语句组成&#xff0c;并且支持以#开头的注释一般包括四个部分&#xff1a;基础镜像信息&#xff0c;维护者信息…

创业的N种死法

点击蓝字关注&#xff0c;回复“职场进阶”获取职场进阶精品资料一份互联网的江湖一直流传着大佬们的创业传奇。马云上厕所几分钟敲定几千万美金融资。王石走投无路靠倒卖玉米赚到上百万从此逆袭。扎克伯格为了获得哈佛美女照片&#xff0c;开发一个小玩意从此改变了世界。传奇…

Docker容器实战思维

Docker成功的基础 Docker的实现用到的基础技术&#xff08;cgroups, namespace&#xff0c;分层文件系统&#xff09;在Docker之前已经存在很多年&#xff0c;并且 Linux Containers&#xff08;LXC&#xff09;也在很多企业的环境中得到了大量的应用实践&#xff0c;并得到明…

dotNET Core 3.X 请求处理管道和中间件的理解

理解 dotNET Core 中的管道模型&#xff0c;对我们学习 dotNET Core 有很大的好处&#xff0c;能让我们知其然&#xff0c;也知其所以然&#xff0c;这样在使用第三方组件或者自己写一些扩展时&#xff0c;可以避免入坑&#xff0c;或者说避免同样的问题多次入坑。本文分为以下…

了解.NET中的垃圾回收

原文来自互联网&#xff0c;由长沙DotNET技术社区编译。尽管这是一篇来自2009年的古老的文章&#xff0c;但或许能够对你理解GC产生一些作用。 了解.NET中的垃圾回收一旦了解了.NET的垃圾收集器是如何工作的&#xff0c;那么可能会触及.NET应用程序的一些更为神秘的问题时&…

数据结构与算法--数组:二维数组中查找

数组 数组最简单的是数据结构&#xff0c;占据一整块连续的内存并按照顺序存储数据&#xff0c;创建数组时候&#xff0c;我们需要首先指定数组的容量大小&#xff0c;然后根据大小分配内存。即使我们只在数组中存储一个元素&#xff0c;亚需要为所有数据预先分配内存&#xf…

数据结构与算法--字符串:字符串替换

数据结构与算法–字符串&#xff1a;字符串替换 字符串的优化 由于字符串在编程时候使用的评率非常高&#xff0c;为了优化&#xff0c;很多语言都对字符串做了特殊的规定。下面我们讨论java中字符串的特性java中的字符数组以’\0’ 结尾&#xff0c;我们可以利用这个特性来找…

数据结构与算法--经典10大排序算法(动图演示)【建议收藏】

十大经典排序算法总结&#xff08;动图演示&#xff09; 算法分类 十大常见排序算法可分为两大类&#xff1a; 比较排序算法&#xff1a;通过比较来决定元素的位置&#xff0c;由于时间复杂度不能突破O(nlogn)&#xff0c;因此也称为非线性时间比较类排序非比较类型排序&…

如何查找,修复和避免C#.NET中内存泄漏的8个最佳实践

原文来自互联网&#xff0c;由长沙DotNET技术社区编译。本文来源&#xff1a;https://michaelscodingspot.com/find-fix-and-avoid-memory-leaks-in-c-net-8-best-practices/从事大型企业项目的任何人都知道内存泄漏就像是大型酒店中的老鼠。当它们很少时&#xff0c;您可能不会…

ASP.NET Core技术研究-探秘依赖注入框架

ASP.NET Core在底层内置了一个依赖注入框架&#xff0c;通过依赖注入的方式注册服务、提供服务。依赖注入不仅服务于ASP.NET Core自身&#xff0c;同时也是应用程序的服务提供者。毫不夸张的说&#xff0c;ASP.NET Core通过依赖注入实现了各种服务对象的注册和创建&#xff0c;…

Redis遍历方式思考--字典扩容方式

全量遍历keys 工作中线上Redis维护&#xff0c;有时候我们需要查询特定前缀的缓存key列表来手动处理数据。可能是修改值&#xff0c;删除key。那么怎么才能快速的从海量的key中查找到对应的前缀匹配项。Redis提供了一下简单的指令&#xff0c;例如keys用来满足特定正则下的key…

从项目到产品: 软件时代需要价值流架构师 | IDCF

译者&#xff1a;无敌哥原文地址: https://thenewstack.io/the-age-of-software-needs-value-stream-architects/ 本文翻译仅供学习交流之用。原文作者 Mik Kersten 出版了《Project to Product》本系列共四篇文章&#xff0c;分别是01 从项目到产品&#xff1a;软件需要从物理…

Redis高效性探索--线程IO模型,通信协议

Redis线程IO模型 Redis是单线程&#xff0c;这个毋庸置疑Redis单线程能做到这么高的效率&#xff1f;不用怀疑&#xff0c;还有很多其他的服务都是单线程但是也有超高的效率&#xff0c;比如Node.js&#xff0c;Nginx也是单线程。Redis单线程高效原因&#xff1a; Redis所有数…

Redis持久化-深入理解AOF,RDB

持久化 Redis数据全部在内存中&#xff0c;如果宕机&#xff0c;数据必然丢失&#xff0c;因此必须有一种机制保证Redis数据不会因为故障丢失&#xff0c;这就是Redis的持久化机制持久化方式两种&#xff1a;AOF&#xff0c;RDB&#xff0c;如下图 RDB快照模式是一次全量备份&…