Docker:容器软件,可以用来部署我们的业务程序,业务程序可以是mysql、nginx、flask等软件,docker软件的出现颠覆了我们传统的软件安装部署的方式

优势:

  1. 轻量级的虚拟化技术
  2. 消耗资源少
  3. 启动速度快

缺点:

  1. 隔离级别不如虚拟机
  2. 安全性不如虚拟机

三个概念

镜像:image       

        是软件单元,本质上是一个文件,文件里面有应用程序代码、微型操作系统、依赖软件

容器:container       

        运行的镜像,本质上是一个进程,提供服务

        容器的三个状态

        create:刚创建还未启动是该状态

        up:已经启动的容器

        exit:已经推出运行的容器

仓库:repository        

        存放镜像的地方

安装

本文档安装主要是在rocky-linux安装

先卸载以前安装的docker相关的软件,以防冲突(新装系统机器可以不执行此步)

#dnf就是yum 
sudo dnf remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

配置docker安装源

使用阿里云的源,官方的源目前下载不下来,repo仓库文件会下载到/etc/yum.repos.d

sudo dnf -y install dnf-plugins-core
sudo dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装docker

sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

错误1

包下载失败

wget https://download.docker.com/linux/centos/8/x86_64/stable/Packages/containerd.io-1.6.32-3.1.el8.x86_64.rpm
sudo dnf install ./containerd.io-1.6.32-3.1.el8.x86_64.rpm

启动docker

设置开机自启

systemctl start docker

systemctl enable docker

ubuntu安装docker

首先更新 apt 包索引并安装必要的依赖

apt-get update

apt-get install ca-certificates curl gnupg lsb-release

添加Docker的官方GPG密钥

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

#如果curl失败,可以尝试wget
wget -qO- https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

#验证是否成功
sudo apt-key fingerprint 0EBFCD88

密钥添加成功后,继续执行设置仓库和安装 Docker 的命令,官方可能无法下载,建议使用阿里云源

curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg


echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

然后开始下载安装

apt-get update

apt-get install docker-ce docker-ce-cli containerd.io

安装完成后验证

docker --version

然后替换国内镜像源

tee /etc/docker/daemon.json <<-'EOF'
{
    "registry-mirrors": ["https://docker.xuanyuan.me","https://docker.1panel.live"]
}
EOF

使用

查看镜像

docker images

默认的docker国外源目前已被屏蔽,我们需要配置国内镜像源来进行镜像的拉取

配置国内源

#创建文件夹
mkdir -p /etc/docker

#添加镜像
sudo tee /etc/docker/daemon.json <<-'EOF'
{
    "registry-mirrors": ["https://docker.xuanyuan.me","https://docker.1panel.live"]
}
EOF

#重启docker
sudo systemctl daemon-reload
sudo systemctl stop docker
sudo systemctl start docker

docker国内可用源

https://docker.m.daocloud.io
https://docker.1ms.run


#20251210

拉取镜像

docker pull nginx

导入镜像

下载镜像文件,上传至服务器

开始导入

docker load -i basybox.tar

启动镜像

docker run -d -p 33090:3306 --name sc-mysql-1 --cpu-shares 500 --cpus 2 --cpuset-cpus 0,1 -m 100000000 -e MYSQL_ROOT_PASSWORD='dreamsoft' mysql:5.7.41

#-d 指定后台运行
#-p 指定映射的端口号
#--name    指定启动的容器名字
#--cpu-shares 指定限定使用的cpu算力数,总数为1000
#--cpus    指定限定使用多少个cpu
#--cpuset-cpus    指定只能使用那些cpu
#-m    指定限定使用多少内存,单位是kb
#-e    指定启动的环境变量
#--rm  退出容器后自动删除容器

查看启动的镜像

docker ps -a

#启动容器
docker start [容器名称]

#停止容器
docker stop [容器名称]

删除镜像

docker rmi [镜像名称]

导出镜像

docker save -o nginx.tar nginx

查看容器启动状态

docker stats

查看运行日志

docker logs [容器名字或者ID]

进入容器

docker exec -it [容器ID或名字] bash

容器内部就是一个小型的系统

复制文件

docker cp [文件路径] [容器名称]:[文件路径]


docker cp [容器名称]:[文件路径] [文件路径]

隔离机制

docker进程隔离主要依赖于两个底层技术:

namespace:命名空间,实现隔离

        网络命名空间:网络相关

        进程命名空间:进程相关

        IPC命名空间:类似管道,用于进程间通信

        挂载命名空间:文件系统相关

        UTS命名空间:主机名和域名相关

        用户命名空间:用户相关

        时间命名空间:时间相关

cgroups:资源控制

        其名称源自控制组群(control groups)的缩写,是内核的一个特性,用于限制、记录和隔离一组进程的资源使用(CPU、内存、磁盘 I/O、网络IO等)

Cgroups功能的实现依赖于四个核心概念:子系统、控制组、层级树、任务

子系统:一个内核的组件,一个子系统代表一类资源调度控制器。例如内存子系统可以限制内存的使用量,CPU 子系统可以限制 CPU 的使用时间。子系统是真正实现某类资源的限制的基础

控制组:表示一组进程和一组带有参数的子系统的关联关系。例如,一个进程使用了 CPU 子系统来限制 CPU 的使用时间,则这个进程和 CPU 子系统的关联关系称为控制组

层级树:由一系列的控制组按照树状结构排列组成的。这种排列方式可以使得控制组拥有父子关系,子控制组默认拥有父控制组的属性,也就是子控制组会继承于父控制组

任务:在cgroup中,任务就是一个进程,一个任务可以是多个cgroup的成员,但这些cgroup必须位于不同的层级,子进程自动成为父进程cgroup的成员,可按需求将子进程移到不同的cgroup中

临时设定内存限制,如果需要长期限制,建议设置为service服务项

systemd-run --unit=men-limit-demo --scope -p MemoryMax=500M -p MemorySwapMax=0 /usr/bin/tail /dev/zero


#--unit    设定任务名字
#--scope
#-p        设定限制内容
#MemoryMax 物理内存
#MemorySwapMax    交换内存  =0代表不启用

测试

#消耗内存
tail /dev/zero

#消耗cpu
yum -y install stress-ng

stress-ng -cpu 0 --timeout 60s

微服务

微服务是一种架构,将集中式的拆分成很多单独的服务,每个服务独立部署与维护,之间通过API来通信

优点:高并发、高可用,每个模块的启停不影响其他模块的运行

云计算

通过互联网提供计算服务的模式,按需获取,按使用付费,从而避免了自己购买和维护物理数据中心服务器的付出

私有云:公司自己建立

公有云:阿里云、腾讯云、华为云等

混合云:一部分自建、一部分公有

IaaS:基础设施即服务,提供最底层的 IT 基础设施(服务器、存储、网络、操作系统等),相当于 “云端的硬件出租”

PaaS:平台即服务,基于 IaaS 之上,提供 “开发 + 运行” 的平台(如数据库管理系统、中间件、开发工具),相当于 “云端的开发运行环境”

SaaS:软件即服务,基于 PaaS/IaaS,直接提供成品软件(如办公软件、CRM、视频会议工具),相当于 “云端的软件租用”

serverless:无服务器技术,提供程序代码,到平台上去运行,运行多久,消耗多少资源,付多少钱

容器的网络

查看容器ip地址

docker inspect [容器ID或者容器名字]

查看容器网络类型

docker network ls


NETWORK ID     NAME      DRIVER    SCOPE
d32b7fcbd241   bridge    bridge    local
985cff6dabf4   host      host      local
35170a9b3a45   none      null      local

创建一个网络命名空间

docker network create sc -d host

#-d    指定网络命名空间类型


#启动镜像并指定使用sc网络
docker run --name sc-nginx-2 -d -p 8090:80 --network sc nginx

四类网络模式

host模式

如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口

bridge模式

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中,是默认的模式

null模式

使用null模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等

container模式

overlay:覆盖网络

是在现有underlay网络之上通过软件虚拟化技术构建的逻辑网络,底层技术使用的是VXLAN协议,

可以解决和其他机器上进行通信的问题

underlay:底层网络

指物理的、基础的网络

卷是一个存储空间,数据存储在卷里,卷理解为一个载体,存储的载体,卷帮助容器实现数据持久化,实现了宿主机和容器的数据共享

查看卷

docker volume ls

创建卷

docker volume create 卷名

#查看卷的详细信息
docker volume inspect 卷名


        "CreatedAt": "2025-09-12T10:24:58+08:00",    #创建时间
        "Driver": "local",                           #挂载类型
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/dist/_data",    #挂载点
        "Name": "dist",                                        #卷名
        "Options": null,
        "Scope": "local"

删除卷

docker volume rm 卷名

挂载卷

docker run --name nginx-3 --mount source=dist,target=/usr/share/nginx/html -d -p 8081:80 nginx


#以下两种方式都可以挂载
--mount source=卷名 target=对应地址
--v     卷名/目的地址:对应地址

多个容器挂载同一个卷

docker volume create v1

mkdir -p /var/lib/docker/volumes/v1/app1
mkdir -p /var/lib/docker/volumes/v1/app2


docker run -d --name nginx-1 -p 8080:80 --mount src=v1,dst=var/log/app1,volume-subpath=app1

docker run -d --name nginx-2 -p 8080:80 --mount src=v1,dst=var/log/app2,volume-subpath=app2

#volume-subpath 指定文件具体选用的文件夹

创建卷挂在NFS服务器

docker volume create --driver local --opt type=nfs --opt  o=addr=192.168.52.130,nolock,soft,ro,sync  --opt  device=:/web/html   nfs-web-1


--opt    #选项
o=addr=192.168.52.130,nolock,soft,ro,sync    #指定NFS服务地址
device                                       #指定NFS共享的文件夹

然后启动容器时指定卷就好了

容器启动过程

  1. 解析启动指令与配置校验

  2. 加载镜像并构建容器根文件系统(RootFS)

  3. 创建容器进程的隔离环境(Namespace 初始化)

  4. 配置资源限制(Cgroups 初始化)

  5. 初始化容器内环境与启动应用进程

  6. 注册容器到 Docker 守护进程

容器访问

--link

docker run -d --name nginx-2 -p 8080:80 --link nginx-1:nginx1 nginx

--link 要链接的容器的名字:hostsname
#这样会在容器的hosts文件内加上一条要访问的容器的IP地址和容器的对应

镜像

容器镜像是一个打包文件,类似于压缩包,里面包含了很多文件

包含:微型操作系统+核心代码+依赖库

制作镜像

新建文件夹mydocker,然后新建Dockerfile文件

mkdir /mydocker


vim Dockerfile

放入下列代码

FROM python:2.7-slim        #指定镜像要依赖的基础镜像
WORKDIR /app                #创建工作目录,进入容器时自动进入的目录
ADD . /app                  #将本地文件添加到/app文件夹下,如果是压缩文件会自动解压
RUN pip install --trusted-host  pypi.python.org -r requirements.txt    #指定创建容器的时候需要运行什么命令
EXPOSE 80                   #声明对外的端口是80
ENV NAME World              #声明了两个变量
ENV AUTHOR cali
CMD ["python","app.py"]    #容器启动的时候执行的第一个命令

RUN的使用尽量减少使用,我们如果要运行多个操作,可以使用&&来操作

#&&前一个命令执行成功后就会执行后一个命令
RUN mkdir -p /test && vim /test/test.txt

当文件里面ENTRYPOINT和CMD命令同时存在时,将会把CMD命令作为参数传入ENTRYPOINT里执行

接下来我们新建requirements.txt和app.py,这个两个文件是实际业务需求文件,并不是一定需要

requirements.txt

Flask
Redis

app.py

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

这个文件就是一个简单的使用Python访问redis

开始构建镜像文件

docker build -t sc_friendlyhello_1 .

然后查看镜像

docker images

然后启动两个镜像,redis镜像可以直接去拉取

#启动redis
docker run -d -p 6379:6379 --name redis-1 redis

#启动自建镜像,--line要是redis-1:redis,因为我们的redis容器叫redis-1,而我们在代码里面写好了我们在本地访问的HOSTNAME叫redis
docker run -d -p 8085:80 --name mywebapp --link redis-1:redis sc_friendlyhello_1

最后去浏览器访问页面即可

镜像内部包含了操作系统,但是还是还是这么小,是因为里面的操作系统不自带内核,会自动调用宿主机的内核,我们制作的镜像是越小越好,越小的镜像能够节省更多的:存储资源、内存资源、网络资源

仓库

harbor

安装

首先上传harbor软件包,然后解压软件

tar xf 压缩包名字

解压之后进入harbor文件夹,复制一份配置文件,修改harbor.yml

cp harbor.yml.tmpl harbor.yml

将hostname修改为本机地址,然后修改port(如果有https证书可以启动https服务,没有话需要注释掉)

然后开始安装harbor,在harbor目录底下执行

./install.sh

有下面画面即为成功

然后去浏览器访问harbor,使用hostname:port访问

输入用户名密码进行登录,用户名及密码在配置文件内

登陆进去后点击新建项目,输入项目相关信息,点击确定

然后新建用户,点击用户管理,新建一个用户输入相关信息点击确定

用户新建好后,在项目里面添加成员信息,点击项目->项目名称->成员->用户

名称填写我们刚新建的用户名称,角色选择项目管理员即可

这样一来,我们harbor的配置就算完成了,接下来去需要使用仓库的docker宿主机上修改docker源的配置

{
    "registry-mirrors": ["https://docker.xuanyuan.me","https://docker.1panel.live"],
    "insecure-registries": ["http://192.168.52.135:8080"]#因为我们使用的是http,所以需要在这里添加一个不安全的源

}

配置完成后需要重启docker使配置生效

然后对需要推送的容器进行改名

docker tag sc-nginx:1.1 192.168.52.135:8080/sanchuang/scnginx:1.1
                        #/harbor host:port/仓库名称

改完名后登录进入并推送镜像

docker login 192.168.52.135:8080
#在接下来的提示符里输入我们在harbor里新建的用户名和密码

#推送
docker push 192.168.52.135:8080/sanchuang/scnginx:1.1

等待推送完成后,进入网页即可查看

然后在需要拉取的服务器上也配置好源,就可以拉取了

docker login 192.168.52.135:8080

docker pull 192.168.52.135:8080/sanchuang/scnginx:1.1

如果harbor服务器上的docker重启了,可以在harbor目录下使用以下命令重新启动harbor所有容器

docker compose restart

CICD

持续集成,持续交付

CI/CD 是现代软件开发中核心的自动化实践体系,全称为 Continuous Integration(持续集成) 和 Continuous Delivery/Deployment(持续交付 / 持续部署)。它通过自动化流程打破开发、测试、运维的协作壁垒,实现 “代码提交 - 构建 - 测试 - 发布” 的高效流转,最终提升软件交付质量与速度。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐