Docker容器技术

时间:2024-10-01 07:39:09

Docker 是一个开源的容器化平台,允许开发者封装他们的应用程序及其所有依赖项到一个标准化的单元中,这个单元被称为“容器”。容器可以在任何支持 Docker 的环境中运行,从而确保应用程序的可移植性和一致性。

Docker 的基本概念

  1. 镜像(Image) :Docker 镜像是一个轻量级、独立的、可执行的软件包,包含运行应用程序所需的一切:代码、运行时、库、环境变量和配置文件。
  2. 容器(Container) :容器是镜像的运行实例。它是一个独立、轻量级的运行环境,包含应用程序及其所有依赖项。
  3. 仓库(Repository) :Docker 仓库用于存储和分发镜像。最常见的仓库是 Docker Hub,用户可以从中拉取镜像或推送自己的镜像。

Docker 的优势

  1. 环境一致性:通过使用容器,可以确保应用程序在不同环境中的一致性,避免了由于环境差异导致的问题。
  2. 资源利用率高:Docker 容器是轻量级的,启动和停止快速,可以更高效地使用计算资源,提高系统的资源利用率。
  3. 快速部署:Docker 容器可以在短时间内部署成百上千个应用,更快速交付到线上。
  4. 高效性能:Docker 容器运行在宿主机的操作系统内核之上,相比于传统的虚拟机,少了操作系统以及 Hypervisor 性能的消耗,更加轻量级,节省资源。
  5. 可移植性:Docker 容器可以在不同的环境中轻松地移植和部署应用程序。

Docker 的应用场景

  1. 开发环境搭建:开发者可以使用 Docker 快速搭建一致的开发环境,确保团队成员之间的环境一致性。
  2. 服务依赖管理:Docker 可以帮助管理应用程序的服务依赖,确保每个服务都在独立的容器中运行,便于管理和扩展。
  3. CI/CD 流程:Docker 在持续集成和持续部署(CI/CD)流程中发挥重要作用,确保代码从开发到生产的每个阶段都能在一致的环境中运行。

Docker 的安装和使用

安装 Docker

可以通过官方文档或各种教程学习如何在不同操作系统上安装 Docker。

Docker Docshttps://docs.docker.com/

配置软件仓库
cd /etc/yum.repos.d
vim docker.repo
[docker]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/9/x86_64/stable
gpgcheck=0
安装docker-ce并启动服务
#安装docker
 yum install -y docker-ce 
 systemctl  enable --now docker
 docker info
Activate the web console with: systemctl enable --now cockpit.socket

Register this system with Red Hat Insights: insights-client --register
Create an account or view all your systems at https://red.ht/insights-dashboard
Last login: Sat Sep 28 12:57:57 2024 from 172.25.254.1
[root@docker ~]# docker info
Client: Docker Engine - Community
 Version:    27.1.2
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.16.2
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.29.1
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 13
  Running: 0
  Paused: 0
  Stopped: 13
 Images: 32
 Server Version: 27.1.2
 Storage Driver: overlay2
  Backing Filesystem: xfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 8fc6bcff51318944179630522a095cc9dbf9f353
 runc version: v1.1.13-0-g58aa920
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
 Kernel Version: 5.14.0-362.8.1.el9_3.x86_64
 Operating System: Red Hat Enterprise Linux 9.3 (Plow)
 OSType: linux
 Architecture: x86_64
 CPUs: 8
 Total Memory: 1.692GiB
 Name: docker
 ID: 95ff1944-499d-4ab6-a5a8-5c79ca87a2d7
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

     创建和运行容器

使用 docker load -i <package>加载本地镜像

 使用docker images查看所有镜像

使用 docker run 命令可以创建并运行一个新的容器。

      管理容器

使用 docker ps 查看运行中的容器,使用 docker stop 停止容器,使用 docker rm 删除容器。

Docker 的高级特性

  1. 多阶段构建:通过多阶段构建,可以在构建过程中减少最终镜像的大小,提高构建效率。
  2. 资源限制:可以为容器设置资源限制,如 CPU 和内存使用上限,确保容器不会占用过多系统资源。
  3. 网络模式:Docker 支持多种网络模式,如桥接、主机和覆盖网络等,以满足不同场景的需求。

Docker 通过容器化技术,使得应用程序的开发、部署和管理变得更加高效和一致。无论是开发者还是运维人员,都可以通过学习和使用 Docker,提升工作效率和系统稳定性。

Docker 容器与虚拟机在性能和资源消耗方面的具体比较是什么?

Docker容器与虚拟机(VM)在性能和资源消耗方面有显著差异,主要体现在以下几个方面:

Docker容器可以在几毫秒内启动,而虚拟机通常需要数分钟来启动,因为虚拟机需要加载完整的操作系统。容器共享主机内核,因此开销较低。

Docker容器由于其轻量级架构,不消耗额外的系统资源,使得应用性能高,系统开销小。相比之下,虚拟机由于需要加载整个操作系统,更耗资源。容器共享主机操作系统和部分硬件资源,资源利用率更高。

虚拟机通过硬件虚拟化实现隔离,而容器通过命名空间和cgroup等技术实现进程级别的隔离。虽然两者都提供资源隔离,但容器的隔离性是在进程级别,而虚拟机的隔离性是在硬件级别。

在执行CPU和内存密集型任务时,Docker容器表现更好,并且消耗的电力较少。在数据中心层面,Docker容器能够运行更多的服务,同时使用更少的能量,从而实现更高的能效。

虽然Docker容器在资源利用率和启动速度上有优势,但在某些生产环境中,虚拟机仍是首选,特别是在需要高性能计算或I/O密集型任务时。

总结来说,Docker容器在启动速度、资源消耗和能效方面具有明显优势,适用于需要快速部署和高效利用资源的应用场景。

如何在Docker中实现高效的多阶段构建,并有哪些最佳实践?

在Docker中实现高效的多阶段构建,可以遵循以下最佳实践:

  1. 使用多个基础镜像:通过将构建过程拆分为多个阶段,每个阶段可以使用不同的基础镜像。例如,开发阶段可以使用包含所有开发工具和依赖的镜像,而生产阶段则使用轻量级的镜像,仅包含运行应用程序所需的组件。

  2. 精简镜像大小:在构建过程中,尽量移除不必要的文件和元数据。例如,在开发阶段可以保留调试工具和日志文件,但在生产阶段应尽量精简这些内容。

  3. 分阶段构建:在同一个Dockerfile中定义多个构建阶段,每个阶段独立地构建、测试和优化。这样可以在每个阶段结束时只保留必要的文件和元数据,从而减小最终镜像的大小。

  4. 利用流水线和并行执行策略:通过流水线和并行执行策略优化构建时间,提升开发效率。串行流水线虽然简单,但可能效率较低,因此可以考虑设计并行Docker构建流程,以充分利用现代CI/CD工具。

  5. 调试与生产环境分离:在调试阶段启用所有调试或工具,而在生产阶段尽量精简。这有助于确保生产环境的安全性和性能。

  6. 持续集成与持续部署(CI/CD) :结合CI/CD工具来自动化多阶段构建过程,确保每次构建都能高效且一致地完成。

Docker的网络模式具体有哪些,它们各自适用于什么场景?

Docker支持多种网络模式,每种模式适用于不同的场景。以下是Docker的四种主要网络模式及其适用场景:

  1. Bridge模式

    • 描述:这是Docker的默认网络模式,每个容器都会被分配一个独立的IP地址,并通过一个虚拟网桥(docker0)与外界通信。
    • 适用场景:适用于大多数标准的容器部署场景,需要容器之间进行网络隔离和独立管理的情况。
  2. Host模式

    • 描述:在这种模式下,容器将直接使用宿主机的网络栈,容器内的应用可以直接访问宿主机的网络资源,而不需要任何网络隔离。
    • 适用场景:适用于对网络性能要求极高的场景,例如高性能计算、游戏服务器等,或者需要容器与宿主机共享网络资源的情况。
  3. Container模式

    • 描述:在这种模式下,容器会共享另一个容器的网络栈,这意味着两个容器可以共享相同的网络接口和IP地址。
    • 适用场景:适用于需要容器之间高度集成和共享网络资源的场景,例如微服务架构中的服务间通信。
  4. None模式

    • 描述:在这种模式下,容器不会配置任何网络接口,容器内的应用无法通过网络进行通信。
    • 适用场景:适用于不需要网络通信的应用,或者用于测试和开发环境中的临时容器。
在Docker中设置资源限制的具体方法和步骤是什么?

在Docker中设置资源限制的具体方法和步骤如下:

  1. 了解资源限制的重要性:默认情况下,容器没有资源限制,可以使用主机内核调度程序允许的尽可能多的资源。然而,为了防止容器占用过多资源导致主机性能下降,需要对容器的内存和CPU使用进行限制。

  2. 使用docker run命令设置资源限制:在启动容器时,可以通过docker run命令的运行时配置标志来限制容器的资源使用。例如,可以指定最大内存和CPU使用量。这些标志包括--memory(或-m)用于限制内存,以及--cpus用于限制CPU使用。

  3. 查看和管理资源限制:可以使用docker stats命令来显示容器的资源使用情况,包括CPU、内存和网络I/O等指标。此外,还可以通过查看/sys/fs/cgroup/memory/docker目录下的文件来了解硬限制和软限制。

  4. 动态修改资源限制:如果需要调整已设置的资源限制,可以通过重新运行docker run命令并指定新的资源限制值来实现。例如,可以增大或缩小内存限制。

  5. 检查内核支持情况:某些资源限制功能要求宿主机的内核支持。可以使用docker info命令检查是否支持这些功能。如果发现警告信息提示没有启用某些限制功能(如swap限制),可以通过修改内核参数来消除警告。

  6. 注意事项:不当设置资源限制可能导致容器无法正常运行或主机性能问题。因此,在设置资源限制时应谨慎,并根据实际需求合理配置。

Docker在CI/CD流程中的应用案例有哪些?

Docker在CI/CD流程中的应用案例非常广泛,以下是几个典型的例子:

Docker可以轻松搭建测试环境,并保持测试环境的一致性。例如,使用Docker Compose定义应用程序所需的各种服务,如数据库、缓存和消息队列等,从而在测试过程中方便地构建出一个统一的测试环境。

结合Docker和CI/CD工具(如GitLab CI/CD、Jenkins、Travis CI等),可以实现软件的自动化构建、测试和部署。这种方法不仅提高了开发效率,还确保了开发与生产环境的一致性。

某些公司(如iHealth)基于Docker构建了适合自身需求的DevOps CI/CD流程,通过更轻量级和更灵活的方式,提升了整个开发和运维团队的协作效率。

利用Docker可以显著提高持续集成(CI)的效率。例如,将Docker Hub工作流作为CI工具、提升IO密集型构建的速度、使用Selenium进行自动化测试、在Docker中运行Jenkins等技巧,可以加快开发流水线并提高交付速度和稳定性。

在本地机器上运行Docker时,可以在容器中运行测试,而不是在专用CI/CD服务器上进行测试。这不仅节省了资源,还提高了开发效率。

在嵌入式软件开发中,Docker容器化的静态分析工具(如C/C++test Standard)可以与编译器和构建系统打包在一个容器镜像中,部署到开发者的桌面进行本地命令行扫描。这种设置包括两个独立的Docker容器:一个用于编译器和构建工具,另一个用于执行环境(如精简版的嵌入式Linux)。

Dockerfile实例

 建立构建目录,编写构建文件
[root@server1 ~]# mdkir docker
[root@server1 ~]# cd docker/
[root@server1 docker]#  cp ~/nginx-1.23.3.tar.gz .
[root@server1 docker]# vim Dockerfile
FROM centos:7
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
RUN ./configure --with-http_ssl_module --with-http_stub_status_module
RUN make
RUN make install
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
通过dockerfile生成镜像
[root@server1 docker]# docker build -t webserver:v1 .
测试镜像可用性
[root@server1 docker]# docker images webserver
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
webserver    v1        bfd6774cc216   8 seconds ago   494MB
​
[root@server1 docker]# docker history  webserver:v1
[root@server1 docker]# docker run -d --name checkimage webserver
查看容器详情
[root@server1 docker]# docker inspect  web1

镜像优化方案

镜像优化策略

  • 选择最精简的基础镜像

  • 减少镜像的层数

  • 清理镜像构建的中间产物

镜像优化示例

缩减镜像层

[root@server1 docker]# vim Dockerfile
FROM centos:7 AS build
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.23.3 && yum clean all
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
​
[root@server1 docker]# docker build -t webserver:v2 .
​
[root@server1 docker]# docker images  webserver
REPOSITORY   TAG       IMAGE ID       CREATED             SIZE
webserver    v2        caf0f80f2332   4 seconds ago       317MB
webserver    v1        bfd6774cc216   About an hour ago   494MB
​

多阶段构建

[root@server1 docker]# vim Dockerfile
FROM centos:7 AS build
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.23.3 && yum clean all
​
FROM centos:7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
​
[root@server1 docker]# docker build -t webserver:v3 .
​
[root@server1 docker]# docker images  webserver
REPOSITORY   TAG       IMAGE ID       CREATED             SIZE
webserver    v3        1ac964f2cefe   29 seconds ago      205MB
webserver    v2        caf0f80f2332   3 minutes ago       317MB
webserver    v1        bfd6774cc216   About an hour ago   494MB

使用最精简镜像

使用google提供的最精简镜像

下载地址:

https://github.com/GoogleContainerTools/distrolesshttps://github.com/GoogleContainerTools/distroless

下载镜像:

docker pull gcr.io/distroless/base

利用最精简镜像构建

[root@server1 ~]# mkdir new
[root@server1 ~]# cd new/
[root@server1 new]# vim Dockerfile
FROM nginx:1.23 AS base
​
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONE
​
RUN mkdir -p /opt/var/cache/nginx && \
    cp -a --parents /usr/lib/nginx /opt && \
    cp -a --parents /usr/share/nginx /opt && \
    cp -a --parents /var/log/nginx /opt && \
    cp -aL --parents /var/run /opt && \
    cp -a --parents /etc/nginx /opt && \
    cp -a --parents /etc/passwd /opt && \
    cp -a --parents /etc/group /opt && \
    cp -a --parents /usr/sbin/nginx /opt && \
    cp -a --parents /usr/sbin/nginx-debug /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
    cp -a --parents /usr/lib/x86_64-linux-gnu/libpcre* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
    cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
    cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
    cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime
​
FROM gcr.io/distroless/base-debian11
​
COPY --from=base /opt /
​
EXPOSE 80 443
​
ENTRYPOINT ["nginx", "-g", "daemon off;"]
​
[root@server1 new]# docker build -t webserver:v4 .
​
[root@server1 new]# docker images  webserver
REPOSITORY   TAG       IMAGE ID       CREATED             SIZE
webserver    v4        c0c4e1d49f3d   4 seconds ago       34MB
webserver    v3        1ac964f2cefe   12 minutes ago      205MB
webserver    v2        caf0f80f2332   15 minutes ago      317MB
webserver    v1        bfd6774cc216   About an hour ago   494MB

 Docker 镜像仓库的管理

      

搭建简单的Registry仓库

下载Registry镜像

[root@docker ~]# docker pull registry
Using default tag: latest
latest: Pulling from library/registry
930bdd4d222e: Pull complete
a15309931e05: Pull complete
6263fb9c821f: Pull complete
86c1d3af3872: Pull complete
a37b1bf6a96f: Pull complete
Digest: sha256:12120425f07de11a1b899e418d4b0ea174c8d4d572d45bdb640f93bc7ca06a3d
Status: Downloaded newer image for registry:latest
docker.io/library/registry:latest

开启Registry

[root@docker ~]# docker run  -d -p 5000:5000 --restart=always --name registry registry
bc58d3753a701ae67351fac335b06a4d7f66afa10ae60b992f647117827734c5
[root@docker ~]# docker ps
CONTAINER ID   IMAGE      COMMAND                   CREATED         STATUS         PORTS            NAMES
bc58d3753a70   registry   "/entrypoint.sh /etc…"   7 seconds ago   Up 6 seconds   5000/tcp, 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   registry
 

上传镜像到仓库中

#给要上传的经镜像大标签
[root@docker ~]# docker tag busybox:latest  172.25.254.100:5000/busybox:latest
​
#docker在上传的过程中默认使用https,但是我们并没有建立https认证需要的认证文件所以会报错
[root@docker ~]# docker push 172.25.254.100:5000/busybox:latest
The push refers to repository [172.25.254.100:5000/busybox]
Get "https://172.25.254.100:5000/v2/": dial tcp 172.25.254.100:5000: connect: connection refused
​
​
#配置非加密端口
[root@docker ~]# vim /etc/docker/daemon.json
{
  "insecure-registries" : ["http://172.25.254.100:5000"]
}
​
[root@docker ~]# systemctl restart docker
​
#上传镜像
[root@docker ~]# docker push  172.25.254.100:5000/busybox:latest
The push refers to repository [172.25.254.100:5000/busybox]
d51af96cf93e: Pushed
latest: digest: sha256:28e01ab32c9dbcbaae96cf0d5b472f22e231d9e603811857b295e61197e40a9b size: 527
​
#查看镜像上传
[root@docker ~]# curl 172.25.254.100:5000/v2/_catalog
{"repositories":["busybox"]}

 为Registry提加密传输

#生成认证key和证书
[root@docker ~]#  openssl req -newkey  rsa:4096 \
-nodes -sha256 -keyout certs/timinglee.org.key \
-addext "subjectAltName = DNS:reg.timinglee.org" \      #指定备用名称
-x509 -days 365 -out certs/timinglee.org.crt
​
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Shaanxi
Locality Name (eg, city) [Default City]:Xi'an
Organization Name (eg, company) [Default Company Ltd]:timinglee
Organizational Unit Name (eg, section) []:docker
Common Name (eg, your name or your server's hostname) []:reg.timinglee.org
Email Address []:admin@timinglee.org
#启动registry仓库
[root@docker ~]# docker run -d -p 443:443 --restart=always --name registry \
> --name registry -v /opt/registry:/var/lib/registry \
> -v /root/certs:/certs \
> -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/timinglee.org.crt \
> -e REGISTRY_HTTP_TLS_KEY=/certs/timinglee.org.key registry
测试:

[root@docker docker]# docker push reg.timinglee.org/busybox:latest      #docker客户端没有key和证书
Error response from daemon: Get "https://reg.timinglee.org/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority
#为客户端建立证书
[root@docker docker]# mkdir /etc/docker/certs.d/reg.timinglee.org/ -p
[root@docker docker]# cp /root/certs/timinglee.org.crt  /etc/docker/certs.d/reg.timinglee.org/ca.crt
[root@docker docker]# systemctl restart docker
[root@docker docker]# docker push reg.timinglee.org/busybox:latest                                 The push refers to repository [reg.timinglee.org/busybox]
d51af96cf93e: Pushed
latest: digest: sha256:28e01ab32c9dbcbaae96cf0d5b472f22e231d9e603811857b295e61197e40a9b size: 527
​
​
[root@docker docker]# curl  -k https://reg.timinglee.org/v2/_catalog
{"repositories":["busybox"]}

为仓库建立登陆认证

#安装建立认证文件的工具包
[root@docker docker]# dnf install httpd-tools -y
​
#建立认证文件
[root@docker ~]# mkdir auth
[root@docker ~]# htpasswd -Bc auth/htpasswd timinglee   #-B 强制使用最安全加密方式,默认用md5加密
New password:
Re-type new password:
Adding password for user timinglee
​
​
#添加认证到registry容器中   
[root@docker ~]# docker run -d -p 443:443 --restart=always --name registry \
> --name registry -v /opt/registry:/var/lib/registry \
> -v /root/certs:/certs \
> -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/timinglee.org.crt \
> -e REGISTRY_HTTP_TLS_KEY=/certs/timinglee.org.key \
> -v /root/auth:/auth \
> -e "REGISTRY_AUTH=htpasswd" \
> -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
> -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
> registry
​
​
[root@docker ~]# curl -k https://reg.timinglee.org/v2/_catalog -u timinglee:lee
{"repositories":["busybox","nginx"]}
​
#登陆测试
[root@docker ~]# docker login reg.timinglee.org
Username: timinglee
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-stores
​
Login Succeeded
​
​

当仓库开启认证后必须登陆仓库才能进行镜像上传

#未登陆情况下上传镜像
[root@docker ~]# docker push  reg.timinglee.org/busybox
Using default tag: latest
The push refers to repository [reg.timinglee.org/busybox]
d51af96cf93e: Preparing
no basic auth credentials
​
#未登陆请款下也不能下载
[root@docker-node2 ~]# docker pull reg.timinglee.org/busybox
Using default tag: latest
Error response from daemon: Head "https://reg.timinglee.org/v2/busybox/manifests/latest": no basic auth credentials

构建企业级私有仓库

下载软件包地址

https://github.com/goharbor/harbor/releases

Harbor 是由vmware公司开源的企业级 Docker Registry 项目。

它提供了以下主要功能和特点:

  1. 基于角色的访问控制(RBAC):可以为不同的用户和用户组分配不同的权限,增强了安全性和管理的灵活性。

  2. 镜像复制:支持在不同的 Harbor 实例之间复制镜像,方便在多个数据中心或环境中分发镜像。

  3. 图形化用户界面(UI):提供了直观的 Web 界面,便于管理镜像仓库、项目、用户等。

  4. 审计日志:记录了对镜像仓库的各种操作,有助于追踪和审查活动。

  5. 垃圾回收:可以清理不再使用的镜像,节省存储空间。

 部署harbor

[root@docker ~]# tar zxf harbor-offline-installer-v2.5.4.tgz
[root@docker ~]# ls
anaconda-ks.cfg  certs   harbor-offline-installer-v2.5.4.tgz
auth             harbor
[root@docker ~]# cd harbor/
​
​
[root@docker harbor]# cp harbor.yml.tmpl harbor.yml
[root@docker harbor]# vim harbor.yml
​
  hostname: reg.timinglee.org
  certificate: /data/certs/timinglee.org.crt
  private_key: /data/certs/timinglee.org.key
  harbor_admin_password: lee
​
[root@docker harbor]# ./install.sh --help
​
​
Please set --with-notary                #证书签名
Please set --with-trivy                 #安全扫描
Please set --with-chartmuseum if needs enable Chartmuseum in Harbor
​
​
[root@docker harbor]# ./install.sh --with-chartmuseum
#管理harbor的容器
[root@docker harbor]# docker compose stop
[root@docker harbor]# docker compose  up -d

管理仓库

1.登陆

2.建立仓库项目

 上传镜像

[root@docker harbor]# docker login reg.timinglee.org
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-stores
​
Login Succeeded
​
[root@docker harbor]# docker tag busybox:latest  reg.timinglee.org/timinglee/busybox:latest
[root@docker harbor]# docker push reg.timinglee.org/timinglee/busybox:latest
The push refers to repository [reg.timinglee.org/timinglee/busybox]
d51af96cf93e: Pushed
latest: digest: sha256:28e01ab32c9dbcbaae96cf0d5b472f22e231d9e603811857b295e61197e40a9b size: 527

查看上传的镜像

 Docker网络

Docker网络是容器化技术中的一个重要组成部分,它允许容器之间以及容器与外部世界之间进行通信。Docker提供了多种网络模式,每种模式都有其特定的用途和适用场景。以下是Docker的主要网络模式及其详细说明:

  1. Bridge模式

    • 这是Docker的默认网络模式。在这种模式下,Docker会为每个容器创建一个独立的网络命名空间,并分配一个独立的IP地址。容器通过一个虚拟网桥(通常是docker0)与外界通信。这种模式确保了容器之间的网络通信是隔离的,避免了信息泄露和攻击。
  2. Host模式

    • 在这种模式下,容器与宿主机共享网络命名空间,容器直接使用宿主机的网络接口。这意味着容器不会获得独立的IP地址,而是直接使用宿主机的IP地址。这种模式适用于需要高性能网络连接的场景。
  3. None模式

    • 在这种模式下,Docker容器拥有自己的网络命名空间,但不进行任何网络配置。容器只有lo回环网络,没有其他网卡。这种模式适用于不需要网络连接的场景,例如某些后台服务或批处理任务。
  4. Container模式

    • 在这种模式下,新创建的容器与指定的现有容器共享网络命名空间。这意味着两个容器共享相同的网络接口和IP地址。这种模式适用于需要共享网络环境的场景。
  5. Custom模式

    • 这是Docker的高级网络配置选项,允许用户创建自定义的网络。用户可以定义网络的子网、网关、DNS等参数,并将多个容器连接到同一个自定义网络中。这种模式适用于复杂的网络拓扑和多容器应用。
  6. Overlay模式

    • 这种模式主要用于Docker Swarm集群中,允许跨多个主机的容器进行通信。Overlay网络通过VXLAN等技术实现跨主机的虚拟网络连接,确保容器之间的通信不受物理网络限制。

docker的自定义网络

自定义网络模式,docker提供了三种自定义网络驱动:

  • bridge

  • overlay

  • macvlan

bridge驱动类似默认的bridge网络模式,但增加了一些新的功能,

overlay和macvlan是用于创建跨主机网络

建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址。

 自定义桥接网络

在建立自定以网络时,默认使用桥接模式

[root@docker ~]# docker network create my_net1
f2aae5ce8ce43e8d1ca80c2324d38483c2512d9fb17b6ba60d05561d6093f4c4
[root@docker ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
2a93d6859680   bridge    bridge    local
4d81ddd9ed10   host      host      local
f2aae5ce8ce4   my_net1   bridge    local
8c8c95f16b68   none      null      local

桥接默认是单调递增

[root@docker ~]# ifconfig
br-f2aae5ce8ce4: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:70:57:f2:82  txqueuelen 0  (Ethernet)
        RX packets 21264  bytes 1497364 (1.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 27359  bytes 215202367 (205.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
​
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:5fff:fee2:346c  prefixlen 64  scopeid 0x20<link>
        ether 02:42:5f:e2:34:6c  txqueuelen 0  (Ethernet)
        RX packets 21264  bytes 1497364 (1.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 27359  bytes 215202367 (205.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
​

桥接也支持自定义子网和网关

[root@docker ~]# docker network create my_net2 --subnet 192.168.0.0/24 --gateway 192.168.0.100
7e77cd2e44c64ff3121a1f1e0395849453f8d524d24b915672da265615e0e4f9
[root@docker ~]# docker network  inspect my_net2
[
    {
        "Name": "my_net2",
        "Id": "7e77cd2e44c64ff3121a1f1e0395849453f8d524d24b915672da265615e0e4f9",
        "Created": "2024-08-17T17:05:19.167808342+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/24",
                    "Gateway": "192.168.0.100"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
[root@docker ~]# docker run  -d --name web1 nginx
d5da7eaa913fa6cdd2aa9a50561042084eca078c114424cb118c57eeac473424
[root@docker ~]# docker run  -d --name web2 nginx
0457a156b02256915d4b42f6cc52ea71b18cf9074ce550c886f206fef60dfae5
[root@docker ~]# docker inspect  web1
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null,
                    "NetworkID": "2a93d6859680b45eae97e5f6232c3b8e070b1ec3d01852b147d2e1385034bce5",
                    "EndpointID": "4d54b12aeb2d857a6e025ee220741cbb3ef1022848d58057b2aab544bd3a4685",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",      #注意ip信息
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DNSNames": null
​
[root@docker ~]# docker inspect  web1
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null,
                    "NetworkID": "2a93d6859680b45eae97e5f6232c3b8e070b1ec3d01852b147d2e1385034bce5",
                    "EndpointID": "4d54b12aeb2d857a6e025ee220741cbb3ef1022848d58057b2aab544bd3a4685",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",      #注意ip信息
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DNSNames": null
                    
#关闭容器后重启容器,启动顺序调换
[root@docker ~]# docker stop web1 web2
web1
web2
[root@docker ~]# docker start web2
web2
[root@docker ~]# docker start web1
web1
​
#我们会发容器ip颠倒
利用Linux控制组(cgroups)限制Docker容器的资源访问
  1. 理解cgroups的基本概念:cgroups是Linux内核提供的一种机制,用于根据需求将一系列任务及子任务整合或分隔到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。它可以根据需求限制和记录任务组所使用的资源。

  2. 配置cgroups限制:在Docker中,可以通过创建和配置不同子系统(Subsystem)挂载的hierarchy中的cgroup来限制容器的资源使用。具体操作包括初始化Subsystem实例,遍历调用Subsystem实例的Set方法,创建和配置cgroup,最后将容器的进程加入到相应的cgroup中。

  3. 使用Docker命令进行资源限制:在使用docker createdocker run命令创建或运行容器时,可以指定资源限制选项,如内存、CPU、磁盘IO等。Docker通过cgroup来控制容器使用的资源配额。

  4. 深入理解cgroups的工作原理:了解cgroups的工作原理和功能,可以帮助更好地管理和优化系统资源,以满足不同应用的需求。

  5. 结合namespace机制:Docker还利用namespace机制实现资源隔离,通过namespace为进程提供不同的命名空间,实现容器权限的隔离。