容器管理工具 Containerd

轻量级或工业级容器管理工具 Containerd

一、Containerd介绍

1.0 前言

  • 早在2016年3月,Docker 1.11的Docker Engine里就包含了containerd,而现在则是把containerd从Docker Engine里彻底剥离出来,作为一个独立的开源项目独立发展,目标是提供一个更加开放、稳定的容器运行基础设施。和原先包含在Docker Engine里containerd相比,独立的containerd将具有更多的功能,可以涵盖整个容器运行时管理的所有需求。

  • containerd并不是直接面向最终用户的,而是主要用于集成到更上层的系统里,比如Swarm, Kubernetes, Mesos等容器编排系统。

  • containerd以Daemon的形式运行在系统上,通过暴露底层的gRPC API,上层系统可以通过这些API管理机器上的容器。

  • 每个containerd只负责一台机器,Pull镜像,对容器的操作(启动、停止等),网络,存储都是由containerd完成。具体运行容器由runC负责,实际上只要是符合OCI规范的容器都可以支持。

  • 对于容器编排服务来说,运行时只需要使用containerd+runC,更加轻量,容易管理。

  • 独立之后containerd的特性演进可以和Docker Engine分开,专注容器运行时管理,可以更稳定。

容器管理工具 Containerd_第1张图片

容器管理工具 Containerd_第2张图片

1.1 Containerd前世今生

2013年docker公司在推出docker产品后,由于其对全球技术产生了一定的影响力,Google公司明显感觉到自己公司内部所使用的Brog系统江湖地位受到的威胁,希望Docker公司能够与自己联合打造一款开源的容器运行时作为Docker核心依赖,但Docker公司拒绝了;接着Google公司联合RedHat、IBM等公司说服Docker公司把其容器核心技术libcontainer捐给中立社区(OCI,Open Container Intiative),并更名为runC。
为了进一步遏制Docker在未来技术市场影响力,避免在容器市场上Docker一家独大,Google公司带领导RedHat、IBM等成立了CNCF(Cloud Native Computing Fundation)基金会,即云原生计算基金会。CNCF的目标很明确,既然在容器应用领域无法与Docker相抗衡,那就做Google更有经验的技术市场------大规模容器编排应用场景,Google公司把自己内部使用的Brog系统开源------Kubernetes,也就是我们今天所说的云原生技术生态。

2016年Docker公司推出了Docker Swarm,意在一统Docker生态,让Docker既可以实现容器应用管理,也可以实现大规模容器编排,经过近1年左右时间的市场验证后,发现在容器编排方面无法独立抗衡kubernetes,所以Docker公司于2017年正式宣布原生支持Kubernetes,至此,Docker在大规模容器编排应用市场败下阵来,但是Docker依然不甘心失败,把Docker核心依赖Containerd捐给了CNCF,依此说明Docker依旧是一个PaaS平台。

2020年CNCF基金会宣布Kubernetes 1.20版本将不再仅支持Docker容器管理工具,此事的起因主要也与Docker捐给CNCF基金会的Containerd有关,早期为了实现Kubernetes能够使用Docker实现容器管理,专门在Kubernetes组件中集成一个shim(垫片)技术,用来将Kubernetes容器运行时接口(CRI,Container Runntime Interface)调用翻译成Docker的API,这样就可以很好地使用Docker了,但是随着Kubernetes在全球技术市场的广泛应用,有更多的容器管理工具的出现,它们都想能够借助于Kubernetes被用户所使用,所以就提出标准化容器运行时接口,只要适配了这个接口就可以集成到Kubernetes生态当中,所以Kubernetes取消了对shim的维护,并且由于Containerd技术的成功,可以实现无缝对接Kubernetes,所以接下来Kubernetes容器运行时的主角是Containerd。

1.2 Containerd架构

1.2.1 架构图

Containerd设计的目的是为了嵌入到Kubernetes中使用,它是一个工业级的容器运行时,不提供给开发人员和终端用户直接使用,这样就避免了与Docker产生竞争,但事实上,Containerd已经实现大多数容器管理功能,例如:容器生命周期管理、容器镜像传输和管理、容器存储与网络管理等。

  • Containerd 采用标准的 C/S 架构

    • 服务端通过 GRPC 协议提供稳定的 API
    • 客户端通过调用服务端的 API 进行高级的操作
  • 为了实现解耦,Containerd 将不同的职责划分给不同的组件,每个组件就相当于一个子系统(subsystem)。连接不同子系统的组件被称为模块。

  • Containerd 两大子系统为:

    • Bundle : 在 Containerd 中,Bundle 包含了配置、元数据和根文件系统数据,你可以理解为容器的文件系统。而 Bundle 子系统允许用户从镜像中提取和打包 Bundles。
    • Runtime : Runtime 子系统用来执行 Bundles,比如创建容器。

    其中,每一个子系统的行为都由一个或多个模块协作完成(架构图中的 Core 部分)。每一种类型的模块都以插件的形式集成到 Containerd 中,而且插件之间是相互依赖的。

    例如,上图中的每一个长虚线的方框都表示一种类型的插件,包括 Service Plugin、Metadata Plugin、GC Plugin、Runtime Plugin 等,其中 Service Plugin 又会依赖 Metadata Plugin、GC Plugin 和 Runtime Plugin。每一个小方框都表示一个细分的插件,例如 Metadata Plugin 依赖 Containers Plugin、Content Plugin 等。

1.2.2 常用插件

  • Content Plugin : 提供对镜像中可寻址内容的访问,所有不可变的内容都被存储在这里。
  • Snapshot Plugin : 用来管理容器镜像的文件系统快照。镜像中的每一个 layer 都会被解压成文件系统快照,类似于 Docker 中的 graphdriver
  • Metrics : 暴露各个组件的监控指标。

容器管理工具 Containerd_第3张图片

1.2.3 架构缩略图

Containerd 被分为三个大块:StorageMetadataRuntime

容器管理工具 Containerd_第4张图片

1.2.4 与其它容器运行时工具性能对比

这是使用 bucketbench 对 Docker、crio 和 Containerd 的性能测试结果,包括启动、停止和删除容器,以比较它们所耗的时间:

容器管理工具 Containerd_第5张图片

结论: Containerd 在各个方面都表现良好,总体性能优于 Dockercrio

二、Containerd安装

课程操作系统环境为centos7u6

2.1 YUM方式安装

2.1.1 获取YUM源

获取阿里云YUM源
# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
查看YUM源中Containerd软件
# yum list | grep containerd
containerd.io.x86_64                        1.4.12-3.1.el7             docker-ce-stable

2.1.2 使用yum命令安装

安装Containerd.io软件,即可安装Containerd
# yum -y install containerd.io

2.1.3 验证安装及启动服务

使用rpm -qa命令查看是否安装
# rpm -qa | grep containerd
containerd.io-1.4.12-3.1.el7.x86_64
设置containerd服务启动及开机自启动
# systemctl enable containerd
# systemctl start containerd
查看containerd服务启动状态
# systemctl status containerd
● containerd.service - containerd container runtime
   Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; vendor preset: disabled)
   Active: active (running) since 五 2022-02-18 11:38:30 CST; 9s ago 此行第二列及第三列表示其正在运行状态
     Docs: https://containerd.io
  Process: 59437 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
 Main PID: 59439 (containerd)
    Tasks: 7
   Memory: 19.5M
   CGroup: /system.slice/containerd.service
           └─59439 /usr/bin/containerd
           ......

2.1.4 验证可用性

安装Containerd时ctr命令亦可使用,ctr命令主要用于管理容器及容器镜像等。
使用ctr命令查看Containerd客户端及服务端相关信息。
# ctr version
Client:
  Version:  1.4.12
  Revision: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
  Go version: go1.16.10

Server:
  Version:  1.4.12
  Revision: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
  UUID: 3c4b142d-d91d-44a5-aae2-9673785d4b2c

2.2 二进制方式安装

Containerd有两种安装包:

  • 第一种是containerd-xxx,这种包用于单机测试没问题,不包含runC,需要提前安装。
  • 第二种是cri-containerd-cni-xxxx,包含runc和k8s里的所需要的相关文件。k8s集群里需要用到此包。虽然包含runC,但是依赖系统中的seccomp(安全计算模式,是一种限制容器调用系统资源的模式。)

2.2.1 获取安装包

容器管理工具 Containerd_第6张图片

容器管理工具 Containerd_第7张图片

下载Containerd安装包
# wget https://github.com/containerd/containerd/releases/download/v1.6.0/cri-containerd-cni-1.6.0-linux-amd64.tar.gz

2.2.2 安装并测试可用性

2.2.2.1 安装containerd

查看已获取的安装包
# ls
cri-containerd-cni-1.6.0-linux-amd64.tar.gz
解压已下载的软件包
# tar xf cri-containerd-cni-1.6.0-linux-amd64.tar.gz
查看解压后目录
# ls
etc opt  usr 
查看etc目录,主要为containerd服务管理配置文件及cni虚拟网卡配置文件
# ls etc
cni  crictl.yaml  systemd
# ls etc/systemd/
system
# ls etc/systemd/system/
containerd.service


查看opt目录,主要为gce环境中使用containerd配置文件及cni插件
# ls opt
cni  containerd
# ls opt/containerd/
cluster
# ls opt/containerd/cluster/
gce  version
# ls opt/containerd/cluster/gce
cloud-init  cni.template  configure.sh  env

查看usr目录,主要为containerd运行时文件,包含runc
# ls usr
local
# ls usr/local/
bin  sbin
# ls usr/local/bin
containerd  containerd-shim  containerd-shim-runc-v1  containerd-shim-runc-v2  containerd-stress  crictl  critest  ctd-decoder  ctr
# ls usr/local/sbin
runc

2.2.2.2 查看containerd安装位置

查看containerd.service文件,了解containerd文件安装位置
# cat etc/systemd/system/containerd.service



# Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target

[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd 查看此位置,把containerd二进制文件放置于此处即可完成安装。

Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999

[Install]
WantedBy=multi-user.target

2.2.2.3 复制containerd运行时文件至系统

查看宿主机/usr/local/bin目录,里面没有任何内容。
# ls /usr/local/bin/

查看解压后usr/local/bin目录,里面包含containerd运行时文件
# ls usr/
local
# ls usr/local/
bin  sbin
# ls usr/local/bin/
containerd  containerd-shim  containerd-shim-runc-v1  containerd-shim-runc-v2  containerd-stress  crictl  critest  ctd-decoder  ctr

复制containerd文件至/usr/local/bin目录中,本次可仅复制containerd一个文件也可复制全部文件。
# cp usr/local/bin/containerd /usr/local/bin/
# ls /usr/local/bin/
containerd

2.2.2.4 添加containerd.service文件至系统

查看解压后的etc/system目录
# ls etc
cni  crictl.yaml  systemd

# ls etc/systemd/
system

# ls etc/systemd/system/
containerd.service

复制containerd服务管理配置文件至/usr/lib/systemd/system/目录中
# cp etc/systemd/system/containerd.service /usr/lib/systemd/system/containerd.service

查看复制后结果
# ls /usr/lib/systemd/system/containerd.service
/usr/lib/systemd/system/containerd.service

2.2.2.5 查看containerd使用帮助

# containerd --help
NAME:
   containerd -
                    __        _                     __
  _________  ____  / /_____ _(_)___  ___  _________/ /
 / ___/ __ \/ __ \/ __/ __ `/ / __ \/ _ \/ ___/ __  /
/ /__/ /_/ / / / / /_/ /_/ / / / / /  __/ /  / /_/ /
\___/\____/_/ /_/\__/\__,_/_/_/ /_/\___/_/   \__,_/

high performance container runtime


USAGE:
   containerd [global options] command [command options] [arguments...]

VERSION:
   v1.6.0

DESCRIPTION:

containerd is a high performance container runtime whose daemon can be started
by using this command. If none of the *config*, *publish*, or *help* commands
are specified, the default action of the **containerd** command is to start the
containerd daemon in the foreground.


A default configuration is used if no TOML configuration is specified or located
at the default file location. The *containerd config* command can be used to
generate the default configuration for containerd. The output of that command
can be used and modified as necessary as a custom configuration.

COMMANDS:
   config    information on the containerd config
   publish   binary to publish events to containerd
   oci-hook  provides a base for OCI runtime hooks to allow arguments to be injected.
   help, h   Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --config value, -c value     path to the configuration file (default: "/etc/containerd/config.toml")
   --log-level value, -l value  set the logging level [trace, debug, info, warn, error, fatal, panic]
   --address value, -a value    address for containerd's GRPC server
   --root value                 containerd root directory
   --state value                containerd state directory
   --help, -h                   show help
   --version, -v                print the version

2.2.2.6 生成containerd模块配置文件

2.2.2.6.1 生成默认模块配置文件

Containerd 的默认配置文件为 /etc/containerd/config.toml,可以使用containerd config default > /etc/containerd/config.toml命令创建一份模块配置文件

创建配置文件目录
# mkdir /etc/containerd
生成配置文件
# containerd config default > /etc/containerd/config.toml
查看配置文件
# cat /etc/containerd/config.toml
disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
state = "/run/containerd"
temp = ""
version = 2

[cgroup]
  path = ""

[debug]
  address = ""
  format = ""
  gid = 0
  level = ""
  uid = 0

[grpc]
  address = "/run/containerd/containerd.sock"
  gid = 0
  max_recv_message_size = 16777216
  max_send_message_size = 16777216
  tcp_address = ""
  tcp_tls_ca = ""
  tcp_tls_cert = ""
  tcp_tls_key = ""
  uid = 0

[metrics]
  address = ""
  grpc_histogram = false

[plugins]

  [plugins."io.containerd.gc.v1.scheduler"]
    deletion_threshold = 0
    mutation_threshold = 100
    pause_threshold = 0.02
    schedule_delay = "0s"
    startup_delay = "100ms"

  [plugins."io.containerd.grpc.v1.cri"]
    device_ownership_from_security_context = false
    disable_apparmor = false
    disable_cgroup = false
    disable_hugetlb_controller = true
    disable_proc_mount = false
    disable_tcp_service = true
    enable_selinux = false
    enable_tls_streaming = false
    enable_unprivileged_icmp = false
    enable_unprivileged_ports = false
    ignore_image_defined_volumes = false
    max_concurrent_downloads = 3
    max_container_log_line_size = 16384
    netns_mounts_under_state_dir = false
    restrict_oom_score_adj = false
    sandbox_image = "k8s.gcr.io/pause:3.6"  由于网络原因,此处被替换
    selinux_category_range = 1024
    stats_collect_period = 10
    stream_idle_timeout = "4h0m0s"
    stream_server_address = "127.0.0.1"
    stream_server_port = "0"
    systemd_cgroup = false
    tolerate_missing_hugetlb_controller = true
    unset_seccomp_profile = ""

    [plugins."io.containerd.grpc.v1.cri".cni]
      bin_dir = "/opt/cni/bin"
      conf_dir = "/etc/cni/net.d"
      conf_template = ""
      ip_pref = ""
      max_conf_num = 1

    [plugins."io.containerd.grpc.v1.cri".containerd]
      default_runtime_name = "runc"
      disable_snapshot_annotations = true
      discard_unpacked_layers = false
      ignore_rdt_not_enabled_errors = false
      no_pivot = false
      snapshotter = "overlayfs"

      [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
        base_runtime_spec = ""
        cni_conf_dir = ""
        cni_max_conf_num = 0
        container_annotations = []
        pod_annotations = []
        privileged_without_host_devices = false
        runtime_engine = ""
        runtime_path = ""
        runtime_root = ""
        runtime_type = ""

        [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]

      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]

        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
          base_runtime_spec = ""
          cni_conf_dir = ""
          cni_max_conf_num = 0
          container_annotations = []
          pod_annotations = []
          privileged_without_host_devices = false
          runtime_engine = ""
          runtime_path = ""
          runtime_root = ""
          runtime_type = "io.containerd.runc.v2"

          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            BinaryName = ""
            CriuImagePath = ""
            CriuPath = ""
            CriuWorkPath = ""
            IoGid = 0
            IoUid = 0
            NoNewKeyring = false
            NoPivotRoot = false
            Root = ""
            ShimCgroup = ""
            SystemdCgroup = false

      [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
        base_runtime_spec = ""
        cni_conf_dir = ""
        cni_max_conf_num = 0
        container_annotations = []
        pod_annotations = []
        privileged_without_host_devices = false
        runtime_engine = ""
        runtime_path = ""
        runtime_root = ""
        runtime_type = ""

        [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options]

    [plugins."io.containerd.grpc.v1.cri".image_decryption]
      key_model = "node"

    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = ""

      [plugins."io.containerd.grpc.v1.cri".registry.auths]

      [plugins."io.containerd.grpc.v1.cri".registry.configs]

      [plugins."io.containerd.grpc.v1.cri".registry.headers]

      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]

    [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
      tls_cert_file = ""
      tls_key_file = ""

  [plugins."io.containerd.internal.v1.opt"]
    path = "/opt/containerd"

  [plugins."io.containerd.internal.v1.restart"]
    interval = "10s"

  [plugins."io.containerd.internal.v1.tracing"]
    sampling_ratio = 1.0
    service_name = "containerd"

  [plugins."io.containerd.metadata.v1.bolt"]
    content_sharing_policy = "shared"

  [plugins."io.containerd.monitor.v1.cgroups"]
    no_prometheus = false

  [plugins."io.containerd.runtime.v1.linux"]
    no_shim = false
    runtime = "runc"
    runtime_root = ""
    shim = "containerd-shim"
    shim_debug = false

  [plugins."io.containerd.runtime.v2.task"]
    platforms = ["linux/amd64"]
    sched_core = false

  [plugins."io.containerd.service.v1.diff-service"]
    default = ["walking"]

  [plugins."io.containerd.service.v1.tasks-service"]
    rdt_config_file = ""

  [plugins."io.containerd.snapshotter.v1.aufs"]
    root_path = ""

  [plugins."io.containerd.snapshotter.v1.btrfs"]
    root_path = ""

  [plugins."io.containerd.snapshotter.v1.devmapper"]
    async_remove = false
    base_image_size = ""
    discard_blocks = false
    fs_options = ""
    fs_type = ""
    pool_name = ""
    root_path = ""

  [plugins."io.containerd.snapshotter.v1.native"]
    root_path = ""

  [plugins."io.containerd.snapshotter.v1.overlayfs"]
    root_path = ""
    upperdir_label = false

  [plugins."io.containerd.snapshotter.v1.zfs"]
    root_path = ""

  [plugins."io.containerd.tracing.processor.v1.otlp"]
    endpoint = ""
    insecure = false
    protocol = ""

[proxy_plugins]

[stream_processors]

  [stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
    accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
    args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
    env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
    path = "ctd-decoder"
    returns = "application/vnd.oci.image.layer.v1.tar"

  [stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
    accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
    args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
    env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
    path = "ctd-decoder"
    returns = "application/vnd.oci.image.layer.v1.tar+gzip"

[timeouts]
  "io.containerd.timeout.bolt.open" = "0s"
  "io.containerd.timeout.shim.cleanup" = "5s"
  "io.containerd.timeout.shim.load" = "5s"
  "io.containerd.timeout.shim.shutdown" = "3s"
  "io.containerd.timeout.task.state" = "2s"

[ttrpc]
  address = ""
  gid = 0
  uid = 0
2.2.2.6.2 替换默认配置文件

但上述配置文件后期改动的地方较多,这里直接换成可单机使用也可k8s环境使用的配置文件并配置好镜像加速器。

# vim /etc/containerd/config.toml

# cat /etc/containerd/config.toml
root = "/var/lib/containerd"
state = "/run/containerd"
oom_score = -999

[grpc]
  address = "/run/containerd/containerd.sock"
  uid = 0
  gid = 0
  max_recv_message_size = 16777216
  max_send_message_size = 16777216

[debug]
  address = ""
  uid = 0
  gid = 0
  level = ""

[metrics]
  address = ""
  grpc_histogram = false

[cgroup]
  path = ""

[plugins]
  [plugins.cgroups]
    no_prometheus = false
  [plugins.cri]
    stream_server_address = "127.0.0.1"
    stream_server_port = "0"
    enable_selinux = false
    sandbox_image = "easzlab/pause-amd64:3.2"
    stats_collect_period = 10
    systemd_cgroup = false
    enable_tls_streaming = false
    max_container_log_line_size = 16384
    [plugins.cri.containerd]
      snapshotter = "overlayfs"
      no_pivot = false
      [plugins.cri.containerd.default_runtime]
        runtime_type = "io.containerd.runtime.v1.linux"
        runtime_engine = ""
        runtime_root = ""
      [plugins.cri.containerd.untrusted_workload_runtime]
        runtime_type = ""
        runtime_engine = ""
        runtime_root = ""
    [plugins.cri.cni]
      bin_dir = "/opt/kube/bin"
      conf_dir = "/etc/cni/net.d"
      conf_template = "/etc/cni/net.d/10-default.conf"
    [plugins.cri.registry]
      [plugins.cri.registry.mirrors]
        [plugins.cri.registry.mirrors."docker.io"]
          endpoint = [
            "https://docker.mirrors.ustc.edu.cn",
            "http://hub-mirror.c.163.com"
          ]
        [plugins.cri.registry.mirrors."gcr.io"]
          endpoint = [
            "https://gcr.mirrors.ustc.edu.cn"
          ]
        [plugins.cri.registry.mirrors."k8s.gcr.io"]
          endpoint = [
            "https://gcr.mirrors.ustc.edu.cn/google-containers/"
          ]
        [plugins.cri.registry.mirrors."quay.io"]
          endpoint = [
            "https://quay.mirrors.ustc.edu.cn"
          ]
        [plugins.cri.registry.mirrors."harbor.kubemsb.com"] 此处添加了本地容器镜像仓库 Harbor,做为本地容器镜像仓库。
          endpoint = [
            "http://harbor.kubemsb.com"
          ]
    [plugins.cri.x509_key_pair_streaming]
      tls_cert_file = ""
      tls_key_file = ""
  [plugins.diff-service]
    default = ["walking"]
  [plugins.linux]
    shim = "containerd-shim"
    runtime = "runc"
    runtime_root = ""
    no_shim = false
    shim_debug = false
  [plugins.opt]
    path = "/opt/containerd"
  [plugins.restart]
    interval = "10s"
  [plugins.scheduler]
    pause_threshold = 0.02
    deletion_threshold = 0
    mutation_threshold = 100
    schedule_delay = "0s"
    startup_delay = "100ms"

2.2.2.7 启动containerd服务并设置开机自启动

# systemctl enable containerd
Created symlink from /etc/systemd/system/multi-user.target.wants/containerd.service to /usr/lib/systemd/system/containerd.service.
# systemctl start containerd
# systemctl status containerd
● containerd.service - containerd container runtime
   Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; vendor preset: disabled)
   Active: active (running) since 五 2022-02-18 13:02:37 CST; 7s ago
     Docs: https://containerd.io
  Process: 60383 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
 Main PID: 60384 (containerd)
    Tasks: 8
   Memory: 20.0M
   CGroup: /system.slice/containerd.service
           └─60384 /usr/local/bin/containerd
           ......

2.2.2.8 复制ctr命令至系统

# ls usr/local/bin/
containerd  containerd-shim  containerd-shim-runc-v1  containerd-shim-runc-v2  containerd-stress  crictl  critest  ctd-decoder  ctr
# cp usr/local/bin/ctr /usr/bin/

2.2.2.9 查看已安装containerd服务版本

# ctr version
Client:
  Version:  v1.6.0
  Revision: 39259a8f35919a0d02c9ecc2871ddd6ccf6a7c6e
  Go version: go1.17.2

Server:
  Version:  v1.6.0
  Revision: 39259a8f35919a0d02c9ecc2871ddd6ccf6a7c6e
  UUID: c1972cbe-884a-41b0-867f-f8a58c168e6d

2.2.2.10 安装runC

由于二进制包中提供的runC默认需要系统中安装seccomp支持,需要单独安装,且不同版本runC对seccomp版本要求一致,所以建议单独下载runC 二进制包进行安装,里面包含了seccomp模块支持。

2.2.2.10.1 获取runC

容器管理工具 Containerd_第8张图片

使用wget下载
# wget https://github.com/opencontainers/runc/releases/download/v1.1.0/runc.amd64
2.2.2.10.2 安装runC并验证安装结果
查看已下载文件 
# ls
runc.amd64
安装runC
# mv runc.amd64 /usr/sbin/runc
为runC添加可执行权限
# chmod +x /usr/sbin/runc
使用runc命令验证是否安装成功
# runc -v
runc version 1.1.0
commit: v1.1.0-0-g067aaf85
spec: 1.0.2-dev
go: go1.17.6
libseccomp: 2.5.3

三、Containerd容器镜像管理

3.1 Containerd容器镜像管理命令

  • docker使用docker images命令管理镜像
  • 单机containerd使用ctr images命令管理镜像,containerd本身的CLI
  • k8s中containerd使用crictl images命令管理镜像,Kubernetes社区的专用CLI工具
获取命令帮助
# ctr --help
NAME:
   ctr -
        __
  _____/ /______
 / ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/

containerd CLI


USAGE:
   ctr [global options] command [command options] [arguments...]

VERSION:
   v1.6.0

DESCRIPTION:

ctr is an unsupported debug and administrative client for interacting
with the containerd daemon. Because it is unsupported, the commands,
options, and operations are not guaranteed to be backward compatible or
stable from release to release of the containerd project.

COMMANDS:
   plugins, plugin            provides information about containerd plugins
   version                    print the client and server versions
   containers, c, container   manage containers
   content                    manage content
   events, event              display containerd events
   images, image, i           manage images
   leases                     manage leases
   namespaces, namespace, ns  manage namespaces
   pprof                      provide golang pprof outputs for containerd
   run                        run a container
   snapshots, snapshot        manage snapshots
   tasks, t, task             manage tasks
   install                    install a new package
   oci                        OCI tools
   shim                       interact with a shim directly
   help, h                    Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug                      enable debug output in logs
   --address value, -a value    address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]
   --timeout value              total timeout for ctr commands (default: 0s)
   --connect-timeout value      timeout for connecting to containerd (default: 0s)
   --namespace value, -n value  namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]
   --help, -h                   show help
   --version, -v                print the version
获取命令帮助
# ctr images
NAME:
   ctr images - manage images

USAGE:
   ctr images command [command options] [arguments...]

COMMANDS:
   check                    check existing images to ensure all content is available locally
   export                   export images
   import                   import images
   list, ls                 list images known to containerd
   mount                    mount an image to a target path
   unmount                  unmount the image from the target
   pull                     pull an image from a remote
   push                     push an image to a remote
   delete, del, remove, rm  remove one or more images by reference
   tag                      tag an image
   label                    set and clear labels for an image
   convert                  convert an image

OPTIONS:
   --help, -h  show help

3.2 查看镜像

# ctr images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS

3.3 下载镜像

containerd支持oci标准的镜像,所以可以直接使用docker官方或dockerfile构建的镜像

# ctr images pull --all-platforms docker.io/library/nginx:alpine

docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3:    done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:050385609d832fae11b007fbbfba77d0bba12bf72bc0dca0ac03e09b1998580f: done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:f2303c6c88653b9a6739d50f611c170b9d97d161c6432409c680f6b46a5f112f:    done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:bef258acf10dc257d641c47c3a600c92f87be4b4ce4a5e4752b3eade7533dcd9:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:8d6ba530f6489d12676d7f61628427d067243ba4a3a512c3e28813b977cb3b0e:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:5288d7ad7a7f84bdd19c1e8f0abb8684b5338f3da86fe9ae1d7f0e9bc2de6595:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:39e51c61c033442d00c40a30b2a9ed01f40205875fbd8664c50b4dc3e99ad5cf:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:ee6f71c6f4a82b2afd01f92bdf6be0079364d03020e8a2c569062e1c06d3822b:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 11.0s                                                                    total:  8.7 Mi (809.5 KiB/s)                                    
unpacking linux/amd64 sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3...
done: 1.860946163s
说明:
这里ctr命令pull镜像时,不能直接把镜像名字写成`nginx:alpine`
查看已下载容器镜像
# ctr images ls
REF                            TYPE                                                      DIGEST                                                                  SIZE    PLATFORMS                                                                                LABELS
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 9.7 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
REF TYPE DIGEST
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3
SIZE PLATFORMS LABELS
9.7 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
指定平台下载容器镜像
# ctr images pull --platform linux/amd64 docker.io/library/nginx:alpine

3.4 镜像挂载

方便查看镜像中包含的内容。

把已下载的容器镜像挂载至当前文件系统
# ctr images mount docker.io/library/nginx:alpine /mnt
sha256:af2fcce448e2e4451a5f4796a9bf9cb5c9b5f88e0d6d10029cada42fb9d268ac
/mnt
[root@localhost ~]# ls /mnt
bin  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
卸载
# umount /mnt

3.5 镜像导出

把容器镜像导出
# ctr i export --all-platforms nginx.img docker.io/library/nginx:alpine
说明
--all-platforms,导出所有平台镜像,本版本为1.6版本,1.4版本不需要添加此选项。
查看已导出容器镜像
# ls
nginx.img

# ls -lh
总用量 196M

-rw-r--r--  1 root root  73M 2月  18 14:48 nginx.img

3.6 镜像删除

删除指定容器镜像
# ctr image rm docker.io/library/nginx:alpine
docker.io/library/nginx:alpine

再次查看容器镜像
[root@192 ~]# ctr images ls
REF TYPE DIGEST SIZE PLATFORMS LABELS

3.7 镜像导入

导入容器镜像
# ctr images import nginx.img
unpacking docker.io/library/nginx:alpine (sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3)...done

3.8 修改镜像tag

# ctr images tag docker.io/library/nginx:alpine nginx:alpine
nginx:alpine
说明:
把docker.io/library/nginx:alpine 修改为 nginx:alpine
查看修改后的容器镜像
# ctr images ls
REF                            TYPE                                                      DIGEST                                                                  SIZE    PLATFORMS                                                                                LABELS
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 9.7 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
nginx:alpine                   application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 9.7 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
修改后对容器镜像做检查比对
# ctr images check
REF                            TYPE                                                      DIGEST                                                                  STATUS         SIZE            UNPACKED
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 complete (7/7) 9.7 MiB/9.7 MiB true

nginx:alpine                   application/vnd.docker.distribution.manifest.list.v2+json sha256:da9c94bec1da829ebd52431a84502ec471c8e548ffb2cedbf36260fd9bd1d4d3 complete (7/7) 9.7 MiB/9.7 MiB true

四、Containerd容器管理

4.1 获取命令帮助

4.1.1 获取ctr命令帮助

[root@localhost ~]# ctr --help
NAME:
   ctr -
        __
  _____/ /______
 / ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/

containerd CLI


USAGE:
   ctr [global options] command [command options] [arguments...]

VERSION:
   v1.6.0

DESCRIPTION:

ctr is an unsupported debug and administrative client for interacting
with the containerd daemon. Because it is unsupported, the commands,
options, and operations are not guaranteed to be backward compatible or
stable from release to release of the containerd project.

COMMANDS:
   plugins, plugin            provides information about containerd plugins
   version                    print the client and server versions
   containers, c, container   manage containers
   content                    manage content
   events, event              display containerd events
   images, image, i           manage images
   leases                     manage leases
   namespaces, namespace, ns  manage namespaces
   pprof                      provide golang pprof outputs for containerd
   run                        run a container
   snapshots, snapshot        manage snapshots
   tasks, t, task             manage tasks
   install                    install a new package
   oci                        OCI tools
   shim                       interact with a shim directly
   help, h                    Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug                      enable debug output in logs
   --address value, -a value    address for containerd's GRPC server (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]
   --timeout value              total timeout for ctr commands (default: 0s)
   --connect-timeout value      timeout for connecting to containerd (default: 0s)
   --namespace value, -n value  namespace to use with commands (default: "default") [$CONTAINERD_NAMESPACE]
   --help, -h                   show help
   --version, -v                print the version

4.1.2 获取创建静态容器命令帮助

# ctr container --help
NAME:
   ctr containers - manage containers

USAGE:
   ctr containers command [command options] [arguments...]

COMMANDS:
   create                   create container
   delete, del, remove, rm  delete one or more existing containers
   info                     get info about a container
   list, ls                 list containers
   label                    set and clear labels for a container
   checkpoint               checkpoint a container
   restore                  restore a container from checkpoint

OPTIONS:
   --help, -h  show help
说明:

使用`ctr container create `命令创建容器后,容器并没有处于运行状态,其只是一个静态的容器。这个 container 对象只是包含了运行一个容器所需的资源及配置的数据结构,例如: namespaces、rootfs 和容器的配置都已经初始化成功了,只是用户进程(本案例为nginx)还没有启动。需要使用`ctr tasks`命令才能获取一个动态容器。

4.1.3 获取动态容器命令帮助

# ctr run --help
NAME:
   ctr run - run a container

USAGE:
   ctr run [command options] [flags] Image|RootFS ID [COMMAND] [ARG...]
   
OPTIONS:
   --rm                                    remove the container after running
   --null-io                               send all IO to /dev/null
   --log-uri value                         log uri
   --detach, -d                            detach from the task after it has started execution
   --fifo-dir value                        directory used for storing IO FIFOs
   --cgroup value                          cgroup path (To disable use of cgroup, set to "" explicitly)
   --platform value                        run image for specific platform
   --cni                                   enable cni networking for the container
   --runc-binary value                     specify runc-compatible binary
   --runc-root value                       specify runc-compatible root
   --runc-systemd-cgroup                   start runc with systemd cgroup manager
   --uidmap container-uid:host-uid:length  run inside a user namespace with the specified UID mapping range; specified with the format container-uid:host-uid:length
   --gidmap container-gid:host-gid:length  run inside a user namespace with the specified GID mapping range; specified with the format container-gid:host-gid:length
   --remap-labels                          provide the user namespace ID remapping to the snapshotter via label options; requires snapshotter support
   --cpus value                            set the CFS cpu quota (default: 0)
   --cpu-shares value                      set the cpu shares (default: 1024)
   --snapshotter value                     snapshotter name. Empty value stands for the default value. [$CONTAINERD_SNAPSHOTTER]
   --snapshotter-label value               labels added to the new snapshot for this container.
   --config value, -c value                path to the runtime-specific spec config file
   --cwd value                             specify the working directory of the process
   --env value                             specify additional container environment variables (e.g. FOO=bar)
   --env-file value                        specify additional container environment variables in a file(e.g. FOO=bar, one per line)
   --label value                           specify additional labels (e.g. foo=bar)
   --mount value                           specify additional container mount (e.g. type=bind,src=/tmp,dst=/host,options=rbind:ro)
   --net-host                              enable host networking for the container
   --privileged                            run privileged container
   --read-only                             set the containers filesystem as readonly
   --runtime value                         runtime name (default: "io.containerd.runc.v2")
   --runtime-config-path value             optional runtime config path
   --tty, -t                               allocate a TTY for the container
   --with-ns value                         specify existing Linux namespaces to join at container runtime (format ':')
   --pid-file value                        file path to write the task's pid
   --gpus value                            add gpus to the container
   --allow-new-privs                       turn off OCI spec's NoNewPrivileges feature flag
   --memory-limit value                    memory limit (in bytes) for the container (default: 0)
   --device value                          file path to a device to add to the container; or a path to a directory tree of devices to add to the container
   --cap-add value                         add Linux capabilities (Set capabilities with 'CAP_' prefix)
   --cap-drop value                        drop Linux capabilities (Set capabilities with 'CAP_' prefix)
   --seccomp                               enable the default seccomp profile
   --seccomp-profile value                 file path to custom seccomp profile. seccomp must be set to true, before using seccomp-profile
   --apparmor-default-profile value        enable AppArmor with the default profile with the specified name, e.g. "cri-containerd.apparmor.d"
   --apparmor-profile value                enable AppArmor with an existing custom profile
   --rdt-class value                       name of the RDT class to associate the container with. Specifies a Class of Service (CLOS) for cache and memory bandwidth management.
   --rootfs                                use custom rootfs that is not managed by containerd snapshotter
   --no-pivot                              disable use of pivot-root (linux only)
   --cpu-quota value                       Limit CPU CFS quota (default: -1)
   --cpu-period value                      Limit CPU CFS period (default: 0)
   --rootfs-propagation value              set the propagation of the container rootfs
说明:
使用`ctr run`命令可以创建一个静态容器并使其运行。一步到位运行容器。

4.2 查看容器

container表示静态容器,可用c缩写代表container

# ctr container ls
CONTAINER    IMAGE    RUNTIME

# ctr c ls
CONTAINER    IMAGE    RUNTIME

4.3 查看任务

task表示容器里跑的进程, 可用t缩写代表task

# ctr task ls
TASK    PID    STATUS

# ctr t ls
TASK    PID    STATUS

4.4 创建静态容器

# ctr c create docker.io/library/nginx:alpine nginx1
# ctr container ls
CONTAINER    IMAGE                             RUNTIME
nginx1       docker.io/library/nginx:alpine    io.containerd.runc.v2
查看容器详细信息
# ctr container info nginx1

4.5 静态容器启动为动态容器

复制containerd连接runC垫片工具至系统
# ls usr/local/bin/
containerd  containerd-shim  containerd-shim-runc-v1  containerd-shim-runc-v2  containerd-stress  crictl  critest  ctd-decoder  ctr
[root@localhost ~]# cp usr/local/bin/containerd-shim-runc-v2 /usr/bin/
启动task,即表时在容器中运行了进程,即为动态容器。
# ctr task start -d nginx1
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
说明:
-d表示daemon或者后台的意思,否则会卡住终端
查看容器所在宿主机进程,是以宿主机进程的方式存在的。
# ctr task ls
TASK      PID     STATUS
nginx1    3395    RUNNING
查看容器的进程(都是物理机的进程)
# ctr task ps nginx1
PID     INFO
3395    -
3434    -
物理机查看到相应的进程
# ps -ef | grep 3395
root       3395   3375  0 19:16 ?        00:00:00 nginx: master process nginx -g daemon off;
101        3434   3395  0 19:16 ?        00:00:00 nginx: worker process

4.6 进入容器操作

# ctr task exec --exec-id 1 nginx1 /bin/sh

ifconfig 查看网卡信息
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

curl 127.0.0.1 访问本地提供的web服务
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0<!DOCTYPE html>


Welcome to nginx!<<span class="token operator">/</span>title>
<style>
html <span class="token punctuation">{</span> color-scheme: light dark<span class="token punctuation">;</span> <span class="token punctuation">}</span>
body <span class="token punctuation">{</span> width: 35em<span class="token punctuation">;</span> margin: 0 auto<span class="token punctuation">;</span>
font-family: Tahoma<span class="token punctuation">,</span> Verdana<span class="token punctuation">,</span> Arial<span class="token punctuation">,</span> sans-serif<span class="token punctuation">;</span> <span class="token punctuation">}</span>
<<span class="token operator">/</span>style>
<<span class="token operator">/</span>head>
<body>
<h1>Welcome to nginx!<<span class="token operator">/</span>h1>
<p><span class="token keyword">If</span> you see this page<span class="token punctuation">,</span> the nginx web server is successfully installed and
working<span class="token punctuation">.</span> Further configuration is required<span class="token punctuation">.</span><<span class="token operator">/</span>p>

<p><span class="token keyword">For</span> online documentation and support please refer to
<a href=<span class="token string">"http://nginx.org/"</span>>nginx<span class="token punctuation">.</span>org<<span class="token operator">/</span>a><span class="token punctuation">.</span><br/>
Commercial support is available at
<a href=<span class="token string">"http://nginx.com/"</span>>nginx<span class="token punctuation">.</span>com<<span class="token operator">/</span>a><span class="token punctuation">.</span><<span class="token operator">/</span>p>

<p><em>Thank you <span class="token keyword">for</span> <span class="token keyword">using</span> nginx<span class="token punctuation">.</span><<span class="token operator">/</span>em><<span class="token operator">/</span>p>
<<span class="token operator">/</span>body>
<<span class="token operator">/</span>html>
100   615  100   615    0     0   429k      0 <span class="token operator">--</span>:<span class="token operator">--</span>:<span class="token operator">--</span> <span class="token operator">--</span>:<span class="token operator">--</span>:<span class="token operator">--</span> <span class="token operator">--</span>:<span class="token operator">--</span>:<span class="token operator">--</span>  600k
</code></pre> 
  <pre><code class="prism language-powershell">说明:
为exec进程设定一个id,可以随意输入,只要保证唯一即可,也可使用<span class="token variable">$RANDOM</span>变量。
</code></pre> 
  <h2>4.7 直接运行一个动态容器</h2> 
  <pre><code class="prism language-powershell"><span class="token comment"># ctr run -d --net-host docker.io/library/nginx:alpine nginx2</span>
<span class="token operator">/</span>docker-entrypoint<span class="token punctuation">.</span>sh: <span class="token operator">/</span>docker-entrypoint<span class="token punctuation">.</span>d/ is not empty<span class="token punctuation">,</span> will attempt to perform configuration
<span class="token operator">/</span>docker-entrypoint<span class="token punctuation">.</span>sh: Looking <span class="token keyword">for</span> shell scripts in <span class="token operator">/</span>docker-entrypoint<span class="token punctuation">.</span>d/
</code></pre> 
  <pre><code class="prism language-powershell">说明:
<span class="token operator">*</span> <span class="token operator">-</span>d 代表dameon,后台运行
<span class="token operator">*</span> <span class="token operator">--</span>net-host 代表容器的IP就是宿主机的IP<span class="token punctuation">(</span>相当于docker里的host类型网络<span class="token punctuation">)</span>
</code></pre> 
  <pre><code class="prism language-powershell">查看已运行容器
<span class="token comment"># ctr container ls</span>
CONTAINER    IMAGE                             RUNTIME
nginx2       docker<span class="token punctuation">.</span>io/library/nginx:alpine    io<span class="token punctuation">.</span>containerd<span class="token punctuation">.</span>runc<span class="token punctuation">.</span>v2
</code></pre> 
  <pre><code class="prism language-powershell">查看已运行容器中运行的进程<span class="token punctuation">,</span>既tasks
<span class="token comment"># ctr tasks ls</span>
TASK      PID     STATUS
nginx2    4061    RUNNING
</code></pre> 
  <pre><code class="prism language-powershell">进入容器
<span class="token comment"># ctr task exec --exec-id 1 -t nginx2 /bin/sh</span>
</code></pre> 
  <pre><code class="prism language-powershell"><span class="token operator">/</span> <span class="token comment"># ifconfig </span>
ens33     Link encap:Ethernet  HWaddr 00:0C:29:B1:B6:1D
          inet addr:192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>164  Bcast:192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>255  Mask:255<span class="token punctuation">.</span>255<span class="token punctuation">.</span>255<span class="token punctuation">.</span>0
          inet6 addr: fe80::2b33:40ed:9311:8812/64 Scope:Link
          inet6 addr: fe80::adf4:a8bc:a1c:a9f7/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:55360 errors:0 dropped:0 overruns:0 frame:0
          TX packets:30526 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:53511295 <span class="token punctuation">(</span>51<span class="token punctuation">.</span>0 MiB<span class="token punctuation">)</span>  TX bytes:2735050 <span class="token punctuation">(</span>2<span class="token punctuation">.</span>6 MiB<span class="token punctuation">)</span>

lo        Link encap:Local Loopback
          inet addr:127<span class="token punctuation">.</span>0<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1  Mask:255<span class="token punctuation">.</span>0<span class="token punctuation">.</span>0<span class="token punctuation">.</span>0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:68 errors:0 dropped:0 overruns:0 frame:0
          TX packets:68 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:5916 <span class="token punctuation">(</span>5<span class="token punctuation">.</span>7 KiB<span class="token punctuation">)</span>  TX bytes:5916 <span class="token punctuation">(</span>5<span class="token punctuation">.</span>7 KiB<span class="token punctuation">)</span>

virbr0    Link encap:Ethernet  HWaddr 52:54:00:E9:51:82
          inet addr:192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>122<span class="token punctuation">.</span>1  Bcast:192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>122<span class="token punctuation">.</span>255  Mask:255<span class="token punctuation">.</span>255<span class="token punctuation">.</span>255<span class="token punctuation">.</span>0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 <span class="token punctuation">(</span>0<span class="token punctuation">.</span>0 B<span class="token punctuation">)</span>  TX bytes:0 <span class="token punctuation">(</span>0<span class="token punctuation">.</span>0 B<span class="token punctuation">)</span>
</code></pre> 
  <pre><code class="prism language-powershell">为容器中运行的网站添加网站文件
<span class="token operator">/</span> <span class="token comment"># echo "nginx2" > /usr/share/nginx/html/index.html</span>
<span class="token operator">/</span> <span class="token comment"># exit</span>
</code></pre> 
  <pre><code class="prism language-powershell">在宿主机上访问网站
<span class="token namespace">[root@localhost ~]</span><span class="token comment"># curl 192.168.10.164</span>
nginx2
</code></pre> 
  <h2>4.8 暂停容器</h2> 
  <pre><code class="prism language-powershell">查看容器状态
<span class="token comment"># ctr tasks ls</span>
TASK      PID     STATUS
nginx2    4061    RUNNING
</code></pre> 
  <pre><code class="prism language-powershell">暂停容器
<span class="token comment"># ctr tasks pause nginx2</span>
</code></pre> 
  <pre><code class="prism language-powershell">再次查看容器状态,看到其状态为PAUSED,表示停止。
<span class="token comment"># ctr tasks ls</span>
TASK      PID     STATUS
nginx2    4061    PAUSED
</code></pre> 
  <pre><code class="prism language-powershell"><span class="token namespace">[root@localhost ~]</span><span class="token comment"># curl http://192.168.10.164</span>
在宿主机访问,发现不可以访问到网站
</code></pre> 
  <h2>4.9 恢复容器</h2> 
  <pre><code class="prism language-powershell">使用resume命令恢复容器
<span class="token comment"># ctr tasks resume nginx2</span>
</code></pre> 
  <pre><code class="prism language-powershell">查看恢复后状态
<span class="token comment"># ctr tasks ls</span>
TASK      PID     STATUS
nginx2    4061    RUNNING
</code></pre> 
  <pre><code class="prism language-powershell">在宿主机上访问容器中提供的服务
<span class="token comment"># curl http://192.168.10.164</span>
nginx2
</code></pre> 
  <h2>4.10 停止容器</h2> 
  <pre><code class="prism language-powershell"><span class="token comment"># ctr tasks --help</span>
NAME:
   ctr tasks <span class="token operator">-</span> manage tasks

USAGE:
   ctr tasks command <span class="token namespace">[command options]</span> <span class="token namespace">[arguments...]</span>

COMMANDS:
   attach                   attach to the IO of a running container
   checkpoint               checkpoint a container
   delete<span class="token punctuation">,</span> <span class="token function">del</span><span class="token punctuation">,</span> remove<span class="token punctuation">,</span> <span class="token function">rm</span>  delete one or more tasks
   exec                     execute additional processes in an existing container
   list<span class="token punctuation">,</span> <span class="token function">ls</span>                 list tasks
   <span class="token function">kill</span>                     signal a container <span class="token punctuation">(</span>default: SIGTERM<span class="token punctuation">)</span>
   pause                    pause an existing container
   <span class="token function">ps</span>                       list processes <span class="token keyword">for</span> container
   resume                   resume a paused container
   <span class="token function">start</span>                    <span class="token function">start</span> a container that has been created
   metrics<span class="token punctuation">,</span> metric          get a single <span class="token keyword">data</span> point of metrics <span class="token keyword">for</span> a task with the built-in Linux runtime

OPTIONS:
   <span class="token operator">--</span>help<span class="token punctuation">,</span> <span class="token operator">-</span>h  show help

</code></pre> 
  <pre><code class="prism language-powershell">使用<span class="token function">kill</span>命令停止容器中运行的进程,既为停止容器
<span class="token comment"># ctr tasks kill nginx2</span>
</code></pre> 
  <pre><code class="prism language-powershell">查看容器停止后状态,STATUS为STOPPED
<span class="token comment"># ctr tasks ls</span>
TASK      PID     STATUS
nginx1    3395    RUNNING
nginx2    4061    STOPPED
</code></pre> 
  <h2>4.11 删除容器</h2> 
  <pre><code class="prism language-powershell"><span class="token comment"># ctr tasks delete nginx2</span>
必须先停止tasks或先删除task,再删除容器
</code></pre> 
  <pre><code class="prism language-powershell">查看静态容器,确认其还存在于系统中
<span class="token comment"># ctr container ls</span>
CONTAINER    IMAGE                             RUNTIME
nginx2       docker<span class="token punctuation">.</span>io/library/nginx:alpine    io<span class="token punctuation">.</span>containerd<span class="token punctuation">.</span>runc<span class="token punctuation">.</span>v2
</code></pre> 
  <pre><code class="prism language-powershell">删除容器
<span class="token comment"># ctr container delete nginx2</span>
</code></pre> 
  <h1>五、Containerd使用私有容器镜像仓库 Harbor</h1> 
  <h2>5.1 Harbor准备</h2> 
  <p><a href="http://img.e-com-net.com/image/info8/a09e9626d0b9432f9d49f16b63e21cfb.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/a09e9626d0b9432f9d49f16b63e21cfb.jpg" alt="容器管理工具 Containerd_第9张图片" width="650" height="264" style="border:1px solid black;"></a></p> 
  <p><a href="http://img.e-com-net.com/image/info8/b0477256c9e74d9fa41185b274db244e.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/b0477256c9e74d9fa41185b274db244e.jpg" alt="容器管理工具 Containerd_第10张图片" width="650" height="278" style="border:1px solid black;"></a></p> 
  <h2>5.2 配置Containerd使用Harbor仓库</h2> 
  <h3>5.2.1 Harbor主机名解析</h3> 
  <blockquote> 
   <p>在所有安装containerd宿主机上添加此配置信息。</p> 
  </blockquote> 
  <pre><code class="prism language-powershell"><span class="token comment"># vim /etc/hosts</span>
<span class="token comment"># cat /etc/hosts</span>
127<span class="token punctuation">.</span>0<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1   localhost localhost<span class="token punctuation">.</span>localdomain localhost4 localhost4<span class="token punctuation">.</span>localdomain4
::1         localhost localhost<span class="token punctuation">.</span>localdomain localhost6 localhost6<span class="token punctuation">.</span>localdomain6
192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>165 harbor<span class="token punctuation">.</span>kubemsb<span class="token punctuation">.</span>com
</code></pre> 
  <pre><code class="prism language-powershell">说明
<span class="token operator">*</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>165是harbor的IP

<span class="token operator">*</span> harbor<span class="token punctuation">.</span>kubemsb<span class="token punctuation">.</span>com建议用FQDN形式,如果用类似harbor这种短名,后面下载镜像会出问题
</code></pre> 
  <h3>5.2.2 修改Containerd配置文件</h3> 
  <pre><code class="prism language-powershell">此配置文件已提前替换过,仅修改本地容器镜像仓库地址即可。
<span class="token comment"># vim /etc/containerd/config.toml</span>
<span class="token comment"># cat /etc/containerd/config.toml</span>
root = <span class="token string">"/var/lib/containerd"</span>
state = <span class="token string">"/run/containerd"</span>
oom_score = <span class="token operator">-</span>999

<span class="token namespace">[grpc]</span>
  address = <span class="token string">"/run/containerd/containerd.sock"</span>
  uid = 0
  gid = 0
  max_recv_message_size = 16777216
  max_send_message_size = 16777216

<span class="token namespace">[debug]</span>
  address = <span class="token string">""</span>
  uid = 0
  gid = 0
  level = <span class="token string">""</span>

<span class="token namespace">[metrics]</span>
  address = <span class="token string">""</span>
  grpc_histogram = false

<span class="token namespace">[cgroup]</span>
  path = <span class="token string">""</span>

<span class="token namespace">[plugins]</span>
  <span class="token namespace">[plugins.cgroups]</span>
    no_prometheus = false
  <span class="token namespace">[plugins.cri]</span>
    stream_server_address = <span class="token string">"127.0.0.1"</span>
    stream_server_port = <span class="token string">"0"</span>
    enable_selinux = false
    sandbox_image = <span class="token string">"easzlab/pause-amd64:3.2"</span>
    stats_collect_period = 10
    systemd_cgroup = false
    enable_tls_streaming = false
    max_container_log_line_size = 16384
    <span class="token namespace">[plugins.cri.containerd]</span>
      snapshotter = <span class="token string">"overlayfs"</span>
      no_pivot = false
      <span class="token namespace">[plugins.cri.containerd.default_runtime]</span>
        runtime_type = <span class="token string">"io.containerd.runtime.v1.linux"</span>
        runtime_engine = <span class="token string">""</span>
        runtime_root = <span class="token string">""</span>
      <span class="token namespace">[plugins.cri.containerd.untrusted_workload_runtime]</span>
        runtime_type = <span class="token string">""</span>
        runtime_engine = <span class="token string">""</span>
        runtime_root = <span class="token string">""</span>
    <span class="token namespace">[plugins.cri.cni]</span>
      bin_dir = <span class="token string">"/opt/kube/bin"</span>
      conf_dir = <span class="token string">"/etc/cni/net.d"</span>
      conf_template = <span class="token string">"/etc/cni/net.d/10-default.conf"</span>
    <span class="token namespace">[plugins.cri.registry]</span>
      <span class="token namespace">[plugins.cri.registry.mirrors]</span>
        <span class="token punctuation">[</span>plugins<span class="token punctuation">.</span>cri<span class="token punctuation">.</span>registry<span class="token punctuation">.</span>mirrors<span class="token punctuation">.</span><span class="token string">"docker.io"</span><span class="token punctuation">]</span>
          endpoint = <span class="token punctuation">[</span>
            <span class="token string">"https://docker.mirrors.ustc.edu.cn"</span><span class="token punctuation">,</span>
            <span class="token string">"http://hub-mirror.c.163.com"</span>
          <span class="token punctuation">]</span>
        <span class="token punctuation">[</span>plugins<span class="token punctuation">.</span>cri<span class="token punctuation">.</span>registry<span class="token punctuation">.</span>mirrors<span class="token punctuation">.</span><span class="token string">"gcr.io"</span><span class="token punctuation">]</span>
          endpoint = <span class="token punctuation">[</span>
            <span class="token string">"https://gcr.mirrors.ustc.edu.cn"</span>
          <span class="token punctuation">]</span>
        <span class="token punctuation">[</span>plugins<span class="token punctuation">.</span>cri<span class="token punctuation">.</span>registry<span class="token punctuation">.</span>mirrors<span class="token punctuation">.</span><span class="token string">"k8s.gcr.io"</span><span class="token punctuation">]</span>
          endpoint = <span class="token punctuation">[</span>
            <span class="token string">"https://gcr.mirrors.ustc.edu.cn/google-containers/"</span>
          <span class="token punctuation">]</span>
        <span class="token punctuation">[</span>plugins<span class="token punctuation">.</span>cri<span class="token punctuation">.</span>registry<span class="token punctuation">.</span>mirrors<span class="token punctuation">.</span><span class="token string">"quay.io"</span><span class="token punctuation">]</span>
          endpoint = <span class="token punctuation">[</span>
            <span class="token string">"https://quay.mirrors.ustc.edu.cn"</span>
          <span class="token punctuation">]</span>
        <span class="token punctuation">[</span>plugins<span class="token punctuation">.</span>cri<span class="token punctuation">.</span>registry<span class="token punctuation">.</span>mirrors<span class="token punctuation">.</span><span class="token string">"harbor.kubemsb.com"</span><span class="token punctuation">]</span>   在此处添加<span class="token punctuation">,</span>在镜像加速器下面添加这一段
          endpoint = <span class="token punctuation">[</span>
            <span class="token string">"http://harbor.kubemsb.com"</span>
          <span class="token punctuation">]</span>
    <span class="token namespace">[plugins.cri.x509_key_pair_streaming]</span>
      tls_cert_file = <span class="token string">""</span>
      tls_key_file = <span class="token string">""</span>
  <span class="token namespace">[plugins.diff-service]</span>
    default = <span class="token punctuation">[</span><span class="token string">"walking"</span><span class="token punctuation">]</span>
  <span class="token namespace">[plugins.linux]</span>
    shim = <span class="token string">"containerd-shim"</span>
    runtime = <span class="token string">"runc"</span>
    runtime_root = <span class="token string">""</span>
    no_shim = false
    shim_debug = false
  <span class="token namespace">[plugins.opt]</span>
    path = <span class="token string">"/opt/containerd"</span>
  <span class="token namespace">[plugins.restart]</span>
    interval = <span class="token string">"10s"</span>
  <span class="token namespace">[plugins.scheduler]</span>
    pause_threshold = 0<span class="token punctuation">.</span>02
    deletion_threshold = 0
    mutation_threshold = 100
    schedule_delay = <span class="token string">"0s"</span>
    startup_delay = <span class="token string">"100ms"</span>
</code></pre> 
  <pre><code class="prism language-powershell">重启containerd,以便于重新加载配置文件。
<span class="token comment"># systemctl restart containerd</span>
</code></pre> 
  <h3>5.2.3 ctr下载镜像</h3> 
  <pre><code class="prism language-powershell">下载容器镜像
<span class="token comment"># ctr images pull --platform linux/amd64 docker.io/library/nginx:latest</span>
</code></pre> 
  <pre><code class="prism language-powershell">说明:
<span class="token operator">*</span> <span class="token operator">--</span>platform linux/amd64 指定系统平台,也可以使用<span class="token operator">--</span>all-platforms指定所有平台镜像。

</code></pre> 
  <pre><code class="prism language-powershell">输出:
docker<span class="token punctuation">.</span>io/library/nginx:latest:                                                   resolved       <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
index-sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767:    done           <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
manifest-sha256:bb129a712c2431ecce4af8dde831e980373b26368233ef0f3b2bae9e9ec515ee: done           <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
layer-sha256:b559bad762bec166fd028483dd2a03f086d363ee827d8c98b7268112c508665a:    done           <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
config-sha256:c316d5a335a5cf324b0dc83b3da82d7608724769f6454f6d9a621f3ec2534a5a:   done           <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
layer-sha256:5eb5b503b37671af16371272f9c5313a3e82f1d0756e14506704489ad9900803:    done           <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
layer-sha256:1ae07ab881bd848493ad54c2ba32017f94d1d8dbfd0ba41b618f17e80f834a0f:    done           <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
layer-sha256:78091884b7bea0fa918527207924e9993bcc21bf7f1c9687da40042ceca31ac9:    done           <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
layer-sha256:091c283c6a66ad0edd2ab84cb10edacc00a1a7bc5277f5365c0d5c5457a75aff:    done           <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
layer-sha256:55de5851019b8f65ed6e28120c6300e35e556689d021e4b3411c7f4e90a9704b:    done           <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
elapsed: 20<span class="token punctuation">.</span>0s                                                                    total:  53<span class="token punctuation">.</span>2 M <span class="token punctuation">(</span>2<span class="token punctuation">.</span>7 MiB/s<span class="token punctuation">)</span>
unpacking linux/amd64 sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
done: 3<span class="token punctuation">.</span>028652226s
</code></pre> 
  <pre><code class="prism language-powershell">查看已下载容器镜像
<span class="token comment"># ctr images ls</span>
REF                              <span class="token function">TYPE</span>                                                      DIGEST                                                                  SIZE      PLATFORMS                                                                                                                          LABELS

docker<span class="token punctuation">.</span>io/library/nginx:latest   application/vnd<span class="token punctuation">.</span>docker<span class="token punctuation">.</span>distribution<span class="token punctuation">.</span>manifest<span class="token punctuation">.</span>list<span class="token punctuation">.</span>v2+json sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767 54<span class="token punctuation">.</span>1 MiB  linux/386<span class="token punctuation">,</span>linux/amd64<span class="token punctuation">,</span>linux/arm/v5<span class="token punctuation">,</span>linux/arm/v7<span class="token punctuation">,</span>linux/arm64/v8<span class="token punctuation">,</span>linux/mips64le<span class="token punctuation">,</span>linux/ppc64le<span class="token punctuation">,</span>linux/s390x                            <span class="token operator">-</span>
</code></pre> 
  <h3>5.2.4 ctr上传镜像</h3> 
  <blockquote> 
   <p>上传到Harbor library公有项目</p> 
  </blockquote> 
  <pre><code class="prism language-powershell">重新生成新的tag
<span class="token comment"># ctr images tag docker.io/library/nginx:latest harbor.kubemsb.com/library/nginx:latest</span>
harbor<span class="token punctuation">.</span>kubemsb<span class="token punctuation">.</span>com/library/nginx:latest
</code></pre> 
  <pre><code class="prism language-powershell">查看已生成容器镜像
<span class="token comment"># ctr images ls</span>
REF                                     <span class="token function">TYPE</span>                                                      DIGEST                                                                  SIZE      PLATFORMS                                                                                                                          LABELS
docker<span class="token punctuation">.</span>io/library/nginx:latest          application/vnd<span class="token punctuation">.</span>docker<span class="token punctuation">.</span>distribution<span class="token punctuation">.</span>manifest<span class="token punctuation">.</span>list<span class="token punctuation">.</span>v2+json sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767 54<span class="token punctuation">.</span>1 MiB  linux/386<span class="token punctuation">,</span>linux/amd64<span class="token punctuation">,</span>linux/arm/v5<span class="token punctuation">,</span>linux/arm/v7<span class="token punctuation">,</span>linux/arm64/v8<span class="token punctuation">,</span>linux/mips64le<span class="token punctuation">,</span>linux/ppc64le<span class="token punctuation">,</span>linux/s390x                            <span class="token operator">-</span>
harbor<span class="token punctuation">.</span>kubemsb<span class="token punctuation">.</span>com/library/nginx:latest application/vnd<span class="token punctuation">.</span>docker<span class="token punctuation">.</span>distribution<span class="token punctuation">.</span>manifest<span class="token punctuation">.</span>list<span class="token punctuation">.</span>v2+json sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767 54<span class="token punctuation">.</span>1 MiB  linux/386<span class="token punctuation">,</span>linux/amd64<span class="token punctuation">,</span>linux/arm/v5<span class="token punctuation">,</span>linux/arm/v7<span class="token punctuation">,</span>linux/arm64/v8<span class="token punctuation">,</span>linux/mips64le<span class="token punctuation">,</span>linux/ppc64le<span class="token punctuation">,</span>linux/s390x                            <span class="token operator">-</span>
</code></pre> 
  <pre><code class="prism language-powershell">推送容器镜像至Harbor
<span class="token comment"># ctr images push --platform linux/amd64 --plain-http -u admin:Harbor12345 harbor.kubemsb.com/library/nginx:latest</span>
</code></pre> 
  <pre><code class="prism language-powershell">说明:

<span class="token operator">*</span> 先tag再push
<span class="token operator">*</span> 因为我们harbor是http协议,不是https协议,所以需要加上`<span class="token operator">--</span>plain-http`
<span class="token operator">*</span> `<span class="token operator">--</span>user admin:Harbor12345`指定harbor的用户名与密码
</code></pre> 
  <pre><code class="prism language-powershell">输出:
manifest-sha256:0fd68ec4b64b8dbb2bef1f1a5de9d47b658afd3635dc9c45bf0cbeac46e72101: done           <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
config-sha256:dd025cdfe837e1c6395365870a491cf16bae668218edb07d85c626928a60e478:   done           <span class="token punctuation">|</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token operator">++</span><span class="token punctuation">|</span>
elapsed: 0<span class="token punctuation">.</span>5 s                                                                    total:  9<span class="token punctuation">.</span>3 Ki <span class="token punctuation">(</span>18<span class="token punctuation">.</span>1 KiB/s<span class="token punctuation">)</span>
</code></pre> 
  <p><a href="http://img.e-com-net.com/image/info8/db833f1816db4516bc429a920eb48adc.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/db833f1816db4516bc429a920eb48adc.jpg" alt="容器管理工具 Containerd_第11张图片" width="650" height="232" style="border:1px solid black;"></a></p> 
  <pre><code class="prism language-powershell">下载已上传容器镜像
<span class="token comment"># ctr images pull --plain-http harbor.kubemsb.com/library/nginx:latest</span>
</code></pre> 
  <h1>六、Containerd NameSpace管理</h1> 
  <blockquote> 
   <p>containerd中namespace的作用为:隔离运行的容器,可以实现运行多个容器。</p> 
  </blockquote> 
  <pre><code class="prism language-powershell">查看命令帮助
<span class="token comment"># ctr namespace --help</span>
NAME:
   ctr namespaces <span class="token operator">-</span> manage namespaces

USAGE:
   ctr namespaces command <span class="token namespace">[command options]</span> <span class="token namespace">[arguments...]</span>

COMMANDS:
   create<span class="token punctuation">,</span> c   create a new namespace
   list<span class="token punctuation">,</span> <span class="token function">ls</span>    list namespaces
   remove<span class="token punctuation">,</span> <span class="token function">rm</span>  remove one or more namespaces
   label       <span class="token function">set</span> and clear labels <span class="token keyword">for</span> a namespace

OPTIONS:
   <span class="token operator">--</span>help<span class="token punctuation">,</span> <span class="token operator">-</span>h  show help
</code></pre> 
  <pre><code class="prism language-powershell">列出已有namespace
<span class="token comment"># ctr namespace ls</span>
NAME    LABELS
default
k8s<span class="token punctuation">.</span>io
</code></pre> 
  <pre><code class="prism language-powershell">创建namespace
<span class="token comment"># ctr namespace create kubemsb</span>

<span class="token namespace">[root@localhost ~]</span><span class="token comment"># ctr namespace ls</span>
NAME    LABELS
default
k8s<span class="token punctuation">.</span>io
kubemsb 此命名空间为新添加的
</code></pre> 
  <pre><code class="prism language-powershell">删除namespace
<span class="token comment"># ctr namespace rm kubemsb</span>
kubemsb

再次查看是否删除
<span class="token namespace">[root@localhost ~]</span><span class="token comment"># ctr namespace ls</span>
NAME    LABELS
default
k8s<span class="token punctuation">.</span>io
</code></pre> 
  <pre><code class="prism language-powershell">查看指定namespace中是否有用户进程在运行
<span class="token comment"># ctr -n kubemsb tasks ls</span>
TASK    PID    STATUS
</code></pre> 
  <pre><code class="prism language-powershell">在指定namespace中下载容器镜像
<span class="token comment"># ctr -n kubemsb images pull docker.io/library/nginx:latest</span>
</code></pre> 
  <pre><code class="prism language-powershell">在指定namespace中创建静态容器
<span class="token comment"># ctr -n kubemsb container create docker.io/library/nginx:latest nginxapp</span>
</code></pre> 
  <pre><code class="prism language-powershell">查看在指定namespace中创建的容器
<span class="token comment"># ctr -n kubemsb container ls</span>
CONTAINER    IMAGE                             RUNTIME
nginxapp     docker<span class="token punctuation">.</span>io/library/nginx:latest    io<span class="token punctuation">.</span>containerd<span class="token punctuation">.</span>runc<span class="token punctuation">.</span>v2
</code></pre> 
  <h1>七、Containerd Network管理</h1> 
  <blockquote> 
   <p>默认Containerd管理的容器仅有lo网络,无法访问容器之外的网络,可以为其添加网络插件,使用容器可以连接外网。CNI(Container Network Interface)</p> 
  </blockquote> 
  <h2>7.1 创建CNI网络</h2> 
  <table> 
   <thead> 
    <tr> 
     <th><em>containernetworking</em>/<em>cni</em></th> 
     <th> CNI v1.0.1</th> 
    </tr> 
   </thead> 
   <tbody> 
    <tr> 
     <td><em>containernetworking</em>/<em>plugins</em></td> 
     <td> CNI Plugins v1.0.1</td> 
    </tr> 
   </tbody> 
  </table> 
  <h3>7.1.1 获取CNI工具源码</h3> 
  <p><a href="http://img.e-com-net.com/image/info8/3452cf7076a049b2bf6e5b86eb270357.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/3452cf7076a049b2bf6e5b86eb270357.jpg" alt="容器管理工具 Containerd_第12张图片" width="650" height="389" style="border:1px solid black;"></a></p> 
  <pre><code class="prism language-powershell">使用wget下载cni工具源码包
<span class="token comment"># wget https://github.com/containernetworking/cni/archive/refs/tags/v1.0.1.tar.gz</span>
</code></pre> 
  <pre><code class="prism language-powershell">查看已下载cni工具源码包
<span class="token comment"># ls</span>
v1<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1<span class="token punctuation">.</span>tar<span class="token punctuation">.</span>gz

解压已下载cni工具源码包
<span class="token comment"># tar xf v1.0.1.tar.gz</span>

查看解压后已下载cni工具源码包
<span class="token comment"># ls</span>
cni-1<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1

重命名已下载cni工具源码包目录
<span class="token comment"># mv cni-1.0.1 cni</span>

查看重新命名后目录
<span class="token comment"># ls</span>
cni

查看cni工具目录中包含的文件
<span class="token comment"># ls cni</span>
cnitool             CONTRIBUTING<span class="token punctuation">.</span>md  DCO            go<span class="token punctuation">.</span>mod  GOVERNANCE<span class="token punctuation">.</span>md  LICENSE   MAINTAINERS  plugins    RELEASING<span class="token punctuation">.</span>md  scripts  test<span class="token punctuation">.</span>sh
CODE-OF-CONDUCT<span class="token punctuation">.</span>md  CONVENTIONS<span class="token punctuation">.</span>md   Documentation  go<span class="token punctuation">.</span>sum  libcni         logo<span class="token punctuation">.</span>png  pkg          README<span class="token punctuation">.</span>md  ROADMAP<span class="token punctuation">.</span>md    SPEC<span class="token punctuation">.</span>md
</code></pre> 
  <h3>7.1.2 获取CNI Plugins(CNI插件)</h3> 
  <p><a href="http://img.e-com-net.com/image/info8/b6139dfcad494823ba725be5cbb643c8.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/b6139dfcad494823ba725be5cbb643c8.jpg" alt="容器管理工具 Containerd_第13张图片" width="650" height="218" style="border:1px solid black;"></a></p> 
  <pre><code class="prism language-powershell">使用wget下载cni插件工具源码包
<span class="token comment"># wget https://github.com/containernetworking/plugins/releases/download/v1.0.1/cni-plugins-linux-amd64-v1.0.1.tgz</span>
</code></pre> 
  <pre><code class="prism language-powershell">查看已下载cni插件工具源码包
<span class="token comment"># ls</span>
cni-plugins-linux-amd64-v1<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1<span class="token punctuation">.</span>tgz
cni

创建cni插件工具解压目录
<span class="token comment"># mkdir /home/cni-plugins</span>

解压cni插件工具至上述创建的目录中
<span class="token comment"># tar xf cni-plugins-linux-amd64-v1.0.1.tgz -C /home/cni-plugins</span>

查看解压后目录
<span class="token comment"># ls cni-plugins</span>
bandwidth  bridge  dhcp  firewall  host-device  host-local  ipvlan  loopback  macvlan  portmap  ptp  sbr  static  tuning  vlan  vrf
</code></pre> 
  <h3>7.1.3 准备CNI网络配置文件</h3> 
  <blockquote> 
   <p>准备容器网络配置文件,用于为容器提供网关、IP地址等。</p> 
  </blockquote> 
  <pre><code class="prism language-powershell">创建名为mynet的网络,其中包含名为cni0的网桥
<span class="token comment"># vim /etc/cni/net.d/10-mynet.conf</span>
<span class="token comment"># cat /etc/cni/net.d/10-mynet.conf</span>
<span class="token punctuation">{</span>
  <span class="token string">"cniVersion"</span>: <span class="token string">"1.0.0"</span><span class="token punctuation">,</span>
  <span class="token string">"name"</span>: <span class="token string">"mynet"</span><span class="token punctuation">,</span>
  <span class="token string">"type"</span>: <span class="token string">"bridge"</span><span class="token punctuation">,</span>
  <span class="token string">"bridge"</span>: <span class="token string">"cni0"</span><span class="token punctuation">,</span>
  <span class="token string">"isGateway"</span>: true<span class="token punctuation">,</span>
  <span class="token string">"ipMasq"</span>: true<span class="token punctuation">,</span>
  <span class="token string">"ipam"</span>: <span class="token punctuation">{</span>
    <span class="token string">"type"</span>: <span class="token string">"host-local"</span><span class="token punctuation">,</span>
    <span class="token string">"subnet"</span>: <span class="token string">"10.66.0.0/16"</span><span class="token punctuation">,</span>
    <span class="token string">"routes"</span>: <span class="token punctuation">[</span>
      <span class="token punctuation">{</span> <span class="token string">"dst"</span>: <span class="token string">"0.0.0.0/0"</span> <span class="token punctuation">}</span>
   <span class="token punctuation">]</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> 
  <pre><code class="prism language-powershell"><span class="token comment"># vim /etc/cni/net.d/99-loopback.conf</span>
<span class="token comment"># cat /etc/cni/net.d/99-loopback.conf</span>
<span class="token punctuation">{</span>
  <span class="token string">"cniVerion"</span>: <span class="token string">"1.0.0"</span><span class="token punctuation">,</span>
  <span class="token string">"name"</span>: <span class="token string">"lo"</span><span class="token punctuation">,</span>
  <span class="token string">"type"</span>: <span class="token string">"loopback"</span>
<span class="token punctuation">}</span>
</code></pre> 
  <h3>7.1.4 生成CNI网络</h3> 
  <pre><code class="prism language-powershell">获取epel源
<span class="token comment"># wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo</span>

安装jq
<span class="token comment"># yum -y install jq</span>
</code></pre> 
  <pre><code class="prism language-powershell">进入cni工具目录
<span class="token comment"># cd cni</span>
<span class="token namespace">[root@localhost cni]</span><span class="token comment"># ls</span>
cnitool             CONTRIBUTING<span class="token punctuation">.</span>md  DCO            go<span class="token punctuation">.</span>mod  GOVERNANCE<span class="token punctuation">.</span>md  LICENSE   MAINTAINERS  plugins    RELEASING<span class="token punctuation">.</span>md  scripts  test<span class="token punctuation">.</span>sh
CODE-OF-CONDUCT<span class="token punctuation">.</span>md  CONVENTIONS<span class="token punctuation">.</span>md   Documentation  go<span class="token punctuation">.</span>sum  libcni         logo<span class="token punctuation">.</span>png  pkg          README<span class="token punctuation">.</span>md  ROADMAP<span class="token punctuation">.</span>md    SPEC<span class="token punctuation">.</span>md


必须在scripts目录中执行,需要依赖exec-plugins<span class="token punctuation">.</span>sh文件,再次进入scripts目录
<span class="token namespace">[root@localhost cni]</span><span class="token comment"># cd scripts/ </span>

查看执行脚本文件
<span class="token namespace">[root@localhost scripts]</span><span class="token comment"># ls</span>
docker-run<span class="token punctuation">.</span>sh  exec-plugins<span class="token punctuation">.</span>sh  priv-net-run<span class="token punctuation">.</span>sh  release<span class="token punctuation">.</span>sh

执行脚本文件,基于<span class="token operator">/</span>etc/cni/net<span class="token punctuation">.</span>d/目录中的<span class="token operator">*</span><span class="token punctuation">.</span>conf配置文件生成容器网络
<span class="token namespace">[root@localhost scripts]</span><span class="token comment"># CNI_PATH=/home/cni-plugins ./priv-net-run.sh echo "Hello World"</span>
Hello World
</code></pre> 
  <pre><code class="prism language-powershell">在宿主机上查看是否生成容器网络名为cni0的网桥
<span class="token comment"># ip a s</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
5: cni0: <NO-CARRIER<span class="token punctuation">,</span>BROADCAST<span class="token punctuation">,</span>MULTICAST<span class="token punctuation">,</span>UP> mtu 1500 qdisc noqueue state DOWN <span class="token function">group</span> default qlen 1000
    link/ether 36:af:7a:4a:d6:12 brd ff:ff:ff:ff:ff:ff
    inet 10<span class="token punctuation">.</span>66<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1/16 brd 10<span class="token punctuation">.</span>66<span class="token punctuation">.</span>255<span class="token punctuation">.</span>255 scope global cni0
       valid_lft forever preferred_lft forever
    inet6 fe80::34af:7aff:fe4a:d612/64 scope link
       valid_lft forever preferred_lft forever
</code></pre> 
  <pre><code class="prism language-powershell">在宿主机上查看其路由表情况
<span class="token comment"># ip route</span>
default via 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>2 dev ens33 proto dhcp metric 100
10<span class="token punctuation">.</span>66<span class="token punctuation">.</span>0<span class="token punctuation">.</span>0/16 dev cni0 proto kernel scope link src 10<span class="token punctuation">.</span>66<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1
192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>0/24 dev ens33 proto kernel scope link src 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>164 metric 100
192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>122<span class="token punctuation">.</span>0/24 dev virbr0 proto kernel scope link src 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>122<span class="token punctuation">.</span>1
</code></pre> 
  <h2>7.2 为Containerd容器配置网络功能</h2> 
  <h3>7.2.1 创建一个容器</h3> 
  <pre><code class="prism language-powershell"><span class="token comment"># ctr images ls</span>
REF <span class="token function">TYPE</span> DIGEST SIZE PLATFORMS LABELS

<span class="token comment"># ctr images pull docker.io/library/busybox:latest</span>

<span class="token comment"># ctr run -d docker.io/library/busybox:latest busybox</span>

<span class="token comment"># ctr container ls</span>
CONTAINER    IMAGE                               RUNTIME
busybox      docker<span class="token punctuation">.</span>io/library/busybox:latest    io<span class="token punctuation">.</span>containerd<span class="token punctuation">.</span>runc<span class="token punctuation">.</span>v2

<span class="token comment"># ctr tasks ls</span>
TASK       PID     STATUS
busybox    8377    RUNNING
</code></pre> 
  <h3>7.2.2 进入容器查看其网络情况</h3> 
  <pre><code class="prism language-powershell"><span class="token comment"># ctr tasks exec --exec-id $RANDOM -t busybox sh</span>

<span class="token operator">/</span> <span class="token comment"># ip a s</span>
1: lo: <LOOPBACK<span class="token punctuation">,</span>UP<span class="token punctuation">,</span>LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127<span class="token punctuation">.</span>0<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
</code></pre> 
  <h3>7.2.3 获取容器进程ID及其网络命名空间</h3> 
  <pre><code class="prism language-powershell">在宿主机中完成指定容器进程ID获取
<span class="token comment"># pid=$(ctr tasks ls | grep busybox | awk '{print $2}')</span>
<span class="token comment"># echo $pid</span>
8377

</code></pre> 
  <pre><code class="prism language-powershell">在宿主机中完成指定容器网络命名空间路径获取
<span class="token comment"># netnspath=/proc/$pid/ns/net</span>
<span class="token comment"># echo $netnspath</span>
<span class="token operator">/</span>proc/8377/ns/net
</code></pre> 
  <h3>7.2.4 为指定容器添加网络配置</h3> 
  <pre><code class="prism language-powershell">确认执行脚本文件时所在的目录
<span class="token namespace">[root@localhost scripts]</span><span class="token comment"># pwd</span>
<span class="token operator">/</span>home/cni/scripts
</code></pre> 
  <pre><code class="prism language-powershell">执行脚本文件为容器添加网络配置
<span class="token namespace">[root@localhost scripts]</span><span class="token comment"># CNI_PATH=/home/cni-plugins ./exec-plugins.sh add $pid $netnspath</span>
</code></pre> 
  <pre><code class="prism language-powershell">进入容器确认是否添加网卡信息
<span class="token comment"># ctr tasks exec --exec-id $RANDOM -t busybox sh</span>
<span class="token operator">/</span> <span class="token comment"># ip a s</span>
1: lo: <LOOPBACK<span class="token punctuation">,</span>UP<span class="token punctuation">,</span>LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127<span class="token punctuation">.</span>0<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0@if7: <BROADCAST<span class="token punctuation">,</span>MULTICAST<span class="token punctuation">,</span>UP<span class="token punctuation">,</span>LOWER_UP<span class="token punctuation">,</span>M-DOWN> mtu 1500 qdisc noqueue
    link/ether a2:35:b7:e0:60:0a brd ff:ff:ff:ff:ff:ff
    inet 10<span class="token punctuation">.</span>66<span class="token punctuation">.</span>0<span class="token punctuation">.</span>3/16 brd 10<span class="token punctuation">.</span>66<span class="token punctuation">.</span>255<span class="token punctuation">.</span>255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a035:b7ff:fee0:600a/64 scope link
       valid_lft forever preferred_lft forever
       
在容器中ping容器宿主机IP地址
<span class="token operator">/</span> <span class="token comment"># ping -c 2 192.168.10.164</span>
PING 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>164 <span class="token punctuation">(</span>192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>164<span class="token punctuation">)</span>: 56 <span class="token keyword">data</span> bytes
64 bytes <span class="token keyword">from</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>164: seq=0 ttl=64 time=0<span class="token punctuation">.</span>132 ms
64 bytes <span class="token keyword">from</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>164: seq=1 ttl=64 time=0<span class="token punctuation">.</span>044 ms

<span class="token operator">--</span><span class="token operator">-</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>164 ping statistics <span class="token operator">--</span><span class="token operator">-</span>
2 packets transmitted<span class="token punctuation">,</span> 2 packets received<span class="token punctuation">,</span> 0% packet loss
round-trip min/avg/max = 0<span class="token punctuation">.</span>044/0<span class="token punctuation">.</span>088/0<span class="token punctuation">.</span>132 ms

在容器中ping宿主机所在网络的网关IP地址
<span class="token operator">/</span> <span class="token comment"># ping -c 2 192.168.10.2</span>
PING 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>2 <span class="token punctuation">(</span>192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>2<span class="token punctuation">)</span>: 56 <span class="token keyword">data</span> bytes
64 bytes <span class="token keyword">from</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>2: seq=0 ttl=127 time=0<span class="token punctuation">.</span>338 ms
64 bytes <span class="token keyword">from</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>2: seq=1 ttl=127 time=0<span class="token punctuation">.</span>280 ms

<span class="token operator">--</span><span class="token operator">-</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>2 ping statistics <span class="token operator">--</span><span class="token operator">-</span>
2 packets transmitted<span class="token punctuation">,</span> 2 packets received<span class="token punctuation">,</span> 0% packet loss
round-trip min/avg/max = 0<span class="token punctuation">.</span>280/0<span class="token punctuation">.</span>309/0<span class="token punctuation">.</span>338 ms

在容器中ping宿主机所在网络中的其它主机IP地址
<span class="token operator">/</span> <span class="token comment"># ping -c 2 192.168.10.165</span>
PING 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>165 <span class="token punctuation">(</span>192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>165<span class="token punctuation">)</span>: 56 <span class="token keyword">data</span> bytes
64 bytes <span class="token keyword">from</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>165: seq=0 ttl=63 time=0<span class="token punctuation">.</span>422 ms
64 bytes <span class="token keyword">from</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>165: seq=1 ttl=63 time=0<span class="token punctuation">.</span>908 ms

<span class="token operator">--</span><span class="token operator">-</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>10<span class="token punctuation">.</span>165 ping statistics <span class="token operator">--</span><span class="token operator">-</span>
2 packets transmitted<span class="token punctuation">,</span> 2 packets received<span class="token punctuation">,</span> 0% packet loss
round-trip min/avg/max = 0<span class="token punctuation">.</span>422/0<span class="token punctuation">.</span>665/0<span class="token punctuation">.</span>908 ms

</code></pre> 
  <pre><code class="prism language-powershell">在容器中开启httpd服务
<span class="token operator">/</span> <span class="token comment"># echo "containerd net web test" > /tmp/index.html</span>
<span class="token operator">/</span> <span class="token comment"># httpd -h /tmp</span>

<span class="token operator">/</span> <span class="token comment"># wget -O - -q 127.0.0.1</span>
containerd net web test
<span class="token operator">/</span> <span class="token comment"># exit</span>

</code></pre> 
  <pre><code class="prism language-powershell">在宿主机访问容器提供的httpd服务
<span class="token namespace">[root@localhost scripts]</span><span class="token comment"># curl http://10.66.0.3</span>
containerd net web test
</code></pre> 
  <h1>八、Containerd容器数据持久化存储</h1> 
  <blockquote> 
   <p>实现把宿主机目录挂载至Containerd容器中,实现容器数据持久化存储</p> 
  </blockquote> 
  <pre><code class="prism language-powershell"><span class="token comment"># ctr container create docker.io/library/busybox:latest busybox3 --mount type=bind,src=/tmp,dst=/hostdir,options=rbind:rw</span>
</code></pre> 
  <pre><code class="prism language-powershell">说明:
创建一个静态容器,实现宿主机目录与容器挂载
src=<span class="token operator">/</span>tmp 为宿主机目录
dst=<span class="token operator">/</span>hostdir 为容器中目录
</code></pre> 
  <pre><code class="prism language-powershell">运行用户进程
<span class="token comment"># ctr tasks start -d busybox3 bash</span>
</code></pre> 
  <pre><code class="prism language-powershell">进入容器,查看是否挂载成功
<span class="token comment"># ctr tasks exec --exec-id $RANDOM -t busybox3 sh</span>

<span class="token operator">/</span> <span class="token comment"># ls /hostdir</span>
VMwareDnD
systemd-private-cf1fe70805214c80867e7eb62dff5be7-bolt<span class="token punctuation">.</span>service-MWV1Ju
systemd-private-cf1fe70805214c80867e7eb62dff5be7-chronyd<span class="token punctuation">.</span>service-6B6j8p
systemd-private-cf1fe70805214c80867e7eb62dff5be7-colord<span class="token punctuation">.</span>service-6fI31A
systemd-private-cf1fe70805214c80867e7eb62dff5be7-cups<span class="token punctuation">.</span>service-tuK4zI
systemd-private-cf1fe70805214c80867e7eb62dff5be7-rtkit-daemon<span class="token punctuation">.</span>service-vhP67o
tracker-extract-files<span class="token punctuation">.</span>0
vmware-root_703-3988031936
vmware-root_704-2990744159
vmware-root_713-4290166671


向容器中挂载目录中添加文件
<span class="token operator">/</span> <span class="token comment"># echo "hello world" > /hostdir/test.txt</span>

退出容器
<span class="token operator">/</span> <span class="token comment"># exit</span>

在宿主机上查看被容器挂载的目录中是否添加了新的文件,已添加表明被容器挂载成功,并可以读写此目录中内容。
<span class="token namespace">[root@localhost ~]</span><span class="token comment"># cat /tmp/test.txt</span>
hello world
</code></pre> 
  <h1>九、与其它Containerd容器共享命名空间</h1> 
  <blockquote> 
   <p>当需要与其它Containerd管理的容器共享命名空间时,可使用如下方法。</p> 
  </blockquote> 
  <pre><code class="prism language-powershell"><span class="token comment"># ctr tasks ls</span>
TASK        PID      STATUS
busybox3    13778    RUNNING
busybox     8377     RUNNING
busybox1    12469    RUNNING
</code></pre> 
  <pre><code class="prism language-powershell"><span class="token comment"># ctr container create --with-ns "pid:/proc/13778/ns/pid" docker.io/library/busybox:latest busybox4</span>
<span class="token namespace">[root@localhost ~]</span><span class="token comment"># ctr tasks start -d busybox4 bash</span>
<span class="token namespace">[root@localhost ~]</span><span class="token comment"># ctr tasks exec --exec-id $RANDOM -t busybox3 sh</span>
<span class="token operator">/</span> <span class="token comment"># ps aux</span>
PID   USER     TIME  COMMAND
    1 root      0:00 sh
   20 root      0:00 sh
   26 root      0:00 sh
   32 root      0:00 <span class="token function">ps</span> aux

</code></pre> 
  <h1>十、Docker集成Containerd实现容器管理</h1> 
  <p>目前Containerd主要任务还在于解决容器运行时的问题,对于其周边生态还不完善,所以可以借助Docker结合Containerd来实现Docker完整的功能应用。</p> 
  <pre><code class="prism language-powershell">准备Docker安装YUM源
<span class="token comment"># wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo</span>
</code></pre> 
  <pre><code class="prism language-powershell">安装Docker-ce
<span class="token comment"># yum -y install docker-ce</span>
</code></pre> 
  <pre><code class="prism language-powershell">修改Docker服务文件,以便使用已安装的containerd。
<span class="token comment"># vim /etc/systemd/system/multi-user.target.wants/docker.service</span>

修改前:
<span class="token namespace">[Service]</span>
<span class="token function">Type</span>=notify
<span class="token comment"># the default is not to use systemd for cgroups because the delegate issues still</span>
<span class="token comment"># exists and systemd currently does not support the cgroup feature set required</span>
<span class="token comment"># for containers run by docker</span>
ExecStart=<span class="token operator">/</span>usr/bin/dockerd <span class="token operator">-</span>H fd:<span class="token operator">/</span><span class="token operator">/</span> <span class="token operator">--</span>containerd=<span class="token operator">/</span>run/containerd/containerd<span class="token punctuation">.</span>sock 此处
ExecReload=<span class="token operator">/</span>bin/<span class="token function">kill</span> <span class="token operator">-</span>s HUP <span class="token variable">$MAINPID</span>

修改后:

<span class="token namespace">[Service]</span>
<span class="token function">Type</span>=notify
<span class="token comment"># the default is not to use systemd for cgroups because the delegate issues still</span>
<span class="token comment"># exists and systemd currently does not support the cgroup feature set required</span>
<span class="token comment"># for containers run by docker</span>
ExecStart=<span class="token operator">/</span>usr/bin/dockerd <span class="token operator">--</span>containerd  <span class="token operator">/</span>run/containerd/containerd<span class="token punctuation">.</span>sock <span class="token operator">--</span>debug 此处
ExecReload=<span class="token operator">/</span>bin/<span class="token function">kill</span> <span class="token operator">-</span>s HUP <span class="token variable">$MAINPID</span>
TimeoutSec=0
RestartSec=2
Restart=always

</code></pre> 
  <pre><code class="prism language-powershell">设置docker daemon启动并设置其开机自启动
<span class="token comment"># systemctl daemon-reload</span>
<span class="token comment"># systemctl enable docker</span>
Created symlink <span class="token keyword">from</span> <span class="token operator">/</span>etc/systemd/system/multi-user<span class="token punctuation">.</span>target<span class="token punctuation">.</span>wants/docker<span class="token punctuation">.</span>service to <span class="token operator">/</span>usr/lib/systemd/system/docker<span class="token punctuation">.</span>service<span class="token punctuation">.</span>
<span class="token comment"># systemctl start docker</span>
</code></pre> 
  <pre><code class="prism language-powershell">查看其启动后进程
<span class="token comment"># ps aux | grep docker</span>
root      16270  0<span class="token punctuation">.</span>0  3<span class="token punctuation">.</span>1 1155116 63320 ?       Ssl  12:09   0:00 <span class="token operator">/</span>usr/bin/dockerd <span class="token operator">--</span>containerd <span class="token operator">/</span>run/containerd/containerd<span class="token punctuation">.</span>sock <span class="token operator">--</span>debug
</code></pre> 
  <pre><code class="prism language-powershell">使用docker运行容器
<span class="token comment"># docker run -d nginx:latest</span>
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
219a9c6727bcd162d0a4868746c513a277276a110f47e15368b4229988003c13
</code></pre> 
  <pre><code class="prism language-powershell">使用docker <span class="token function">ps</span>命令查看正在运行的容器
<span class="token comment"># docker ps</span>
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS     NAMES
219a9c6727bc   nginx:latest   <span class="token string">"/docker-entrypoint.…"</span>   14 seconds ago   Up 13 seconds   80/tcp    happy_tu
</code></pre> 
  <pre><code class="prism language-powershell">使用ctr查看是否添加一个新的namespace,本案例中发现添加一个moby命名空间,即为docker使用的命名空间。
<span class="token comment"># ctr namespace ls</span>
NAME    LABELS
default
k8s<span class="token punctuation">.</span>io
kubemsb
moby
</code></pre> 
  <pre><code class="prism language-powershell">查看moby命名空间,发现使用docker run运行的容器包含在其中。
<span class="token comment"># ctr -n moby container ls</span>
CONTAINER                                                           IMAGE    RUNTIME
219a9c6727bcd162d0a4868746c513a277276a110f47e15368b4229988003c13    <span class="token operator">-</span>        io<span class="token punctuation">.</span>containerd<span class="token punctuation">.</span>runc<span class="token punctuation">.</span>v2
</code></pre> 
  <pre><code class="prism language-powershell">使用ctr能够查看到一个正在运行的容器,既表示docker run运行的容器是被containerd管理的。
<span class="token comment"># ctr -n moby tasks ls</span>
TASK                                                                PID      STATUS
219a9c6727bcd162d0a4868746c513a277276a110f47e15368b4229988003c13    16719    RUNNING
</code></pre> 
  <pre><code class="prism language-powershell">使用docker stop停止且使用docker <span class="token function">rm</span>删除容器后再观察,发现容器被删除。
<span class="token comment"># docker stop 219;docker rm 219</span>
219
219

<span class="token comment"># ctr -n moby container ls</span>
CONTAINER    IMAGE    RUNTIME

<span class="token comment"># ctr -n moby tasks ls</span>
TASK    PID    STATUS
</code></pre> 
 </div> 
</div>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1643511329434165248"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(容器,kubernetes)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1901597521428410368.htm"
                           title="MinIo前后端实现" target="_blank">MinIo前后端实现</a>
                        <span class="text-muted">陌路物是人非</span>
<a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/Minio/1.htm">Minio</a>
                        <div>这几天想玩玩Minio,整体来说简单使用起来不复杂(当然也有可能是我配置的太少了)Minio下载我是通过Dokcer在虚拟机上下载的(Docker真好用啊)拉取Minio镜像dockerpullminio/minio启动Minio容器dockerrun-d--nameminio-p9000:9000-p9001:9001-v/root/minio/data:/data-v/root/minio/c</div>
                    </li>
                    <li><a href="/article/1901591344405606400.htm"
                           title="OpenStack Heat模板实战:快速创建用户、容器、网络与云主机类型" target="_blank">OpenStack Heat模板实战:快速创建用户、容器、网络与云主机类型</a>
                        <span class="text-muted">冯·诺依曼的</span>
<a class="tag" taget="_blank" href="/search/openstack/1.htm">openstack</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/ssh/1.htm">ssh</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/%E4%BA%91%E8%AE%A1%E7%AE%97/1.htm">云计算</a>
                        <div>Heat是OpenStack中的编排服务,通过YAML模板自动化资源管理。本文通过4个实战案例,详解如何用Heat模板创建用户体系、Swift容器、网络资源及云主机类型。一、创建用户、Domain、租户及用户绑定目标:在chinaskillsDomain下创建beijing_group租户,并创建用户cloud。#user_create.ymlheat_template_version:2016-</div>
                    </li>
                    <li><a href="/article/1901589190756331520.htm"
                           title="K8S学习之基础三十四:K8S之监控Prometheus部署pod版" target="_blank">K8S学习之基础三十四:K8S之监控Prometheus部署pod版</a>
                        <span class="text-muted">云上艺旅</span>
<a class="tag" taget="_blank" href="/search/K8S%E5%AD%A6%E4%B9%A0/1.htm">K8S学习</a><a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/prometheus/1.htm">prometheus</a><a class="tag" taget="_blank" href="/search/%E4%BA%91%E5%8E%9F%E7%94%9F/1.htm">云原生</a>
                        <div>使用KubernetesPod的方式部署Prometheus是一种常见的方法,尤其是在容器化和微服务架构中。以下是详细的步骤:1.创建命名空间(可选)为了方便管理,可以为Prometheus创建一个单独的命名空间。yaml复制apiVersion:v1kind:Namespacemetadata:name:monitoring将上述内容保存为namespace.yaml,然后应用:bash复制ku</div>
                    </li>
                    <li><a href="/article/1901565117301059584.htm"
                           title="Prometheus架构详解" target="_blank">Prometheus架构详解</a>
                        <span class="text-muted">HeZephyr</span>
<a class="tag" taget="_blank" href="/search/%E5%B7%A5%E5%85%B7/1.htm">工具</a><a class="tag" taget="_blank" href="/search/prometheus/1.htm">prometheus</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a>
                        <div>1Prometheus简介Prometheus是一个开源的系统监控报警工具套件,它最初由SoundCloud开发,并于2016年成为CNCF(云原生计算基金会)托管的第二个项目(第一个是kubernetes)。Prometheus以其简单高效的方式收集指标而闻名,能更好地与容器平台、云平台配合,这使得它在现代云原生环境中非常受欢迎。Prometheus被广泛应用于各种场景中,包括但不限于:应用性能</div>
                    </li>
                    <li><a href="/article/1901560577839394816.htm"
                           title="架构设计与模式之:容器化与云原生架构设计模式" target="_blank">架构设计与模式之:容器化与云原生架构设计模式</a>
                        <span class="text-muted">AI天才研究院</span>
<a class="tag" taget="_blank" href="/search/Python%E5%AE%9E%E6%88%98/1.htm">Python实战</a><a class="tag" taget="_blank" href="/search/DeepSeek/1.htm">DeepSeek</a><a class="tag" taget="_blank" href="/search/R1/1.htm">R1</a><a class="tag" taget="_blank" href="/search/%26amp%3B/1.htm">&</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AEAI%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD%E5%A4%A7%E6%A8%A1%E5%9E%8B/1.htm">大数据AI人工智能大模型</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/1.htm">语言模型</a><a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1/1.htm">架构设计</a>
                        <div>作者:禅与计算机程序设计艺术1.简介当今,企业越来越依赖云计算服务来获得快速、经济和弹性伸缩的能力。云原生架构正逐渐成为主流,而容器技术也已经在为企业提供更灵活、更高效的开发环境。本文将从云原生架构和容器技术的角度出发,结合实际应用场景,系统全面剖析容器化及云原生架构的设计模式及优缺点,并为读者提供参考指导。2.背景介绍什么是云原生?云原生(CloudNative)的概念源于Google在Kube</div>
                    </li>
                    <li><a href="/article/1901539391411646464.htm"
                           title="Java面试精选(1):Spring,SpringMVC,SpringBoot,SpringCloud有什么区别和联系?" target="_blank">Java面试精选(1):Spring,SpringMVC,SpringBoot,SpringCloud有什么区别和联系?</a>
                        <span class="text-muted">Java面试精选</span>
<a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/vue/1.htm">vue</a><a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/1.htm">编程语言</a>
                        <div>简单介绍Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。Spring使你能够编写更干净、更可管理、并且更易于测试的代码。SpringMVC是Spring的一个模块,一个web框架。通过DispatcherServlet,ModelAndView和ViewResolver,开发web应用变得很容易。主要针对的是网站应用程序或者服务开发——URL路由、Session、模板引</div>
                    </li>
                    <li><a href="/article/1901537752537690112.htm"
                           title="深入浅出Docker:从零构建容器化开发能力" target="_blank">深入浅出Docker:从零构建容器化开发能力</a>
                        <span class="text-muted">庸子</span>
<a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>目录一、容器革命:重新定义应用交付二、核心概念体系解析2.1镜像与容器2.2镜像构建哲学三、核心操作指令精要3.1容器生命周期管理3.2镜像管理进阶四、生产级实践指南4.1环境变量管理4.2持久化存储方案4.3网络架构设计五、持续交付流水线集成5.1Dockerfile优化原则5.2多环境配置策略六、安全加固要点一、容器革命:重新定义应用交付在传统软件部署中,环境差异导致的"在我机器上能跑"问题长</div>
                    </li>
                    <li><a href="/article/1901522873273610240.htm"
                           title="css填充容器背景色,一半一种颜色" target="_blank">css填充容器背景色,一半一种颜色</a>
                        <span class="text-muted">77n</span>
<a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/css3/1.htm">css3</a>
                        <div>background:linear-gradient(toright,#C3002F50%,#e8e8e80);</div>
                    </li>
                    <li><a href="/article/1901521233674039296.htm"
                           title="CSS 自适应图片根据 div 大小进行均匀填充" target="_blank">CSS 自适应图片根据 div 大小进行均匀填充</a>
                        <span class="text-muted">前端小助手</span>
<a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/tensorflow/1.htm">tensorflow</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a>
                        <div>目录前言使用object-fit属性示例代码HTMLCSS总结相关阅读1.前言在Web开发中,经常需要图片根据其容器的大小进行自适应填充,使得图片在任何设备和屏幕尺寸下都能保持良好的显示效果。本文将介绍如何使用CSS中的object-fit属性来实现这一需求。2.使用object-fit属性object-fit是一个CSS属性,专门用于控制替换元素(如、等)在其容器内的显示方式。常用的值有:fil</div>
                    </li>
                    <li><a href="/article/1901508749739225088.htm"
                           title="如何配置Kubernetes仪表板dashboard支持http方式并使用ingress-nginx代理访问实践" target="_blank">如何配置Kubernetes仪表板dashboard支持http方式并使用ingress-nginx代理访问实践</a>
                        <span class="text-muted">全栈工程师修炼指南</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%91%E5%8E%9F%E7%94%9F%E8%90%BD%E5%9C%B0%E5%AE%9E%E7%94%A8%E6%8C%87%E5%8D%97/1.htm">云原生落地实用指南</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                        <div>公众号关注「WeiyiGeek」设为「特别关注」,每天带你玩转网络安全运维、应用开发、物联网IOT学习!本章目录:配置Kubernetes-dashboard以支持http方式访问原文地址:https://blog.weiyigeek.top/2021/12-1-583.html1.配置Kubernetes-dashboard以支持http方式访问描述:当前默认安装配置的Kubernetes-da</div>
                    </li>
                    <li><a href="/article/1901486187378438144.htm"
                           title="解决注入mapper报红的问题" target="_blank">解决注入mapper报红的问题</a>
                        <span class="text-muted">Jyannis</span>
<a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/Spring/1.htm">Spring</a><a class="tag" taget="_blank" href="/search/Boot/1.htm">Boot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/mybatis/1.htm">mybatis</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/bean/1.htm">bean</a>
                        <div>在spring系列集成mybatis时,我们经常遇到这样的问题:明明注入没有问题,但是intellijidea会报红。这是因为我们没有手动在代码里把mapper接口注入spring容器中,而@Autowired注入方式默认要求注入的对象必须是在spring容器中存在的。所以idea认为这里的userMapper不存在,而用户(我们)选择注入,是一种错误操作,就报红。那么怎么解决这个问题呢?以下提供</div>
                    </li>
                    <li><a href="/article/1901479886346842112.htm"
                           title="@Mapper、@Service以及@Component" target="_blank">@Mapper、@Service以及@Component</a>
                        <span class="text-muted">MHP小喇叭</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>在Spring框架中,@Mapper、@Service和@Component都是用于标记类的注解,但它们的用途和适用场景不同,以下是它们的核心区别和关系:1.@Component作用:Spring的通用组件注解,标记一个类为Spring管理的Bean,会被自动扫描并注入到容器中。适用场景:适用于任何需要被Spring管理的组件(如工具类、非业务层类)。示例:@Componentpublicclas</div>
                    </li>
                    <li><a href="/article/1901476485043122176.htm"
                           title="docker mysql 迁移_Docker跨服务器迁移" target="_blank">docker mysql 迁移_Docker跨服务器迁移</a>
                        <span class="text-muted">weixin_39687468</span>
<a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E8%BF%81%E7%A7%BB/1.htm">迁移</a>
                        <div>Docker跨服务器迁移Docker的备份方式有export和save两种。export是当前的状态,针对的是容器,dockersave是针对镜像images。一、镜像的迁移—save1.镜像保存登陆到已经部署好镜像的服务器上面,执行以下命令进行导出[root@snowedfiles_backup]#dockersave97fd>docker-image-mysql-5.6.40.tar2.将镜像</div>
                    </li>
                    <li><a href="/article/1901476357506920448.htm"
                           title="docker迁移mysql_Docker迁移Mysql" target="_blank">docker迁移mysql_Docker迁移Mysql</a>
                        <span class="text-muted">麟翛</span>
<a class="tag" taget="_blank" href="/search/docker%E8%BF%81%E7%A7%BBmysql/1.htm">docker迁移mysql</a>
                        <div>这几天遇到一个数据迁移的需求,要把老服务器的数据迁移到新的服务器上去,因为Mysql是放在Docker里面的,所以只需要迁移配置文件和数据卷即可,但是这过程中并不是一帆风顺的,特此记录一下。从旧的服务器上查看Mysql容器的信息。首先使用dockerps来查看正在运行的容器,如果你的容器尚未运行,那么执行这条命令dockerps-a使用dockerinspectContainName查看Mysql</div>
                    </li>
                    <li><a href="/article/1901473706203475968.htm"
                           title="docker容器迁移,以mysql容器为例" target="_blank">docker容器迁移,以mysql容器为例</a>
                        <span class="text-muted">风萧易去情难还</span>
<a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a>
                        <div>在容器化环境中,容器迁移是确保应用程序在不同环境中平滑部署和运行的关键。本文将详细介绍如何将一个正在运行的MySQL容器从一台机器迁移到另一台机器。特别内网安装数据库等软件时,所需依赖和工具下载困难,可以通过镜像迁移方式完成软件安装。一、准备工作在开始迁移之前,我们需要准备以下几项工作:源机器(A机器):正在运行的MySQL容器。#拉取mysql镜像dockerpullmysql:8.0.25#创</div>
                    </li>
                    <li><a href="/article/1901469923553636352.htm"
                           title="云原生:K8s(Kubernetes)高频典型面试题汇总" target="_blank">云原生:K8s(Kubernetes)高频典型面试题汇总</a>
                        <span class="text-muted">老舅的火箭爱扫地</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%91%E5%8E%9F%E7%94%9F/1.htm">云原生</a><a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a>
                        <div>1.简述etcd及其特点?答:etcd是CoreOS团队发起的开源项目,是一个管理配置信息和服务发现(servicediscovery)的项目,它的目标是构建一个高可用的分布式键值(key-value)数据库,基于Go语言实现。特点:l简单:支持REST风格的HTTP+JSONAPIl安全:支持HTTPS方式的访问l快速:支持并发1k/s的写操作l可靠:支持分布式结构,基于Raft的一致性算法,R</div>
                    </li>
                    <li><a href="/article/1901468535591333888.htm"
                           title="Docker 中 MySQL 迁移策略(单节点)" target="_blank">Docker 中 MySQL 迁移策略(单节点)</a>
                        <span class="text-muted">Java咩</span>
<a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a>
                        <div>目录一、简介二、操作流程2.1进入mysql容器2.2导出MySQL数据2.3.将导出的文件复制到宿主机2.4创建DockerCompose配置2.5启动新的Docker容器2.6导入数据到新的容器2.7验证数据2.8删除旧的容器(删除操作需慎重)三、推荐配置四、写在后面一、简介本人发现自己Docker中Mysql的时区不对,导致每次连接数据库都需要设置时区,所以考虑进行数据库迁移,重新搭建一个正</div>
                    </li>
                    <li><a href="/article/1901460845053931520.htm"
                           title="servletcontext的作用详细介绍" target="_blank">servletcontext的作用详细介绍</a>
                        <span class="text-muted">时光旅人01号</span>
<a class="tag" taget="_blank" href="/search/Javaweb/1.htm">Javaweb</a><a class="tag" taget="_blank" href="/search/servlet/1.htm">servlet</a><a class="tag" taget="_blank" href="/search/tomcat/1.htm">tomcat</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/web.xml/1.htm">web.xml</a><a class="tag" taget="_blank" href="/search/http/1.htm">http</a>
                        <div>1、什么是servletcontextweb容器在启动的时候,他会为每个web程序创建一个对应的servletcontext对象,他代表的是当前的web应用:共享数据我在这个Servlet中保存的数据,可以在宁一个servlet中拿到:例子如下设置数据publicclassServlettestextendsHttpServlet{protectedvoiddoPost(HttpServletRe</div>
                    </li>
                    <li><a href="/article/1901435383393087488.htm"
                           title="开源Nextcloud+Onlyoffice实现多人协同在线编辑功能(基本配置)" target="_blank">开源Nextcloud+Onlyoffice实现多人协同在线编辑功能(基本配置)</a>
                        <span class="text-muted">运维归一</span>
<a class="tag" taget="_blank" href="/search/%E5%A4%9A%E4%BA%BA%E5%85%B1%E4%BA%AB%E7%BC%96%E8%BE%91/1.htm">多人共享编辑</a><a class="tag" taget="_blank" href="/search/%E7%A7%81%E4%BA%BA%E7%BD%91%E7%9B%98/1.htm">私人网盘</a><a class="tag" taget="_blank" href="/search/nextcloud/1.htm">nextcloud</a><a class="tag" taget="_blank" href="/search/onlyoffice/1.htm">onlyoffice</a>
                        <div>系统软件版本CentOS7NextCloud21本文只介绍基本安装,不适用于企业级一、安装Nextcloud1、容器方式安装dockerrun-d--namenextcloud-p8000:80-v/data/nextcloud:/var/www</div>
                    </li>
                    <li><a href="/article/1901419995645145088.htm"
                           title="AWS DevOps 面试问题及答案" target="_blank">AWS DevOps 面试问题及答案</a>
                        <span class="text-muted">m0_65697474</span>
<a class="tag" taget="_blank" href="/search/1024%E7%A8%8B%E5%BA%8F%E5%91%98%E8%8A%82/1.htm">1024程序员节</a>
                        <div>常规AWSDevOps问题什么是DevOps?DevOps是一套集成软件开发(Dev)和IT运营(Ops)的实践,旨在缩短开发生命周期并根据业务目标频繁提供功能、修复和更新。使用AWS进行DevOps有哪些好处?AWS提供弹性计算云(EC2)、弹性容器服务(ECS)和ElasticBeanstalk等灵活服务,可帮助自动化和扩展开发和部署管道。功能包括可扩展性、自动化、CI/CD、基础设施即代码(</div>
                    </li>
                    <li><a href="/article/1901411927054151680.htm"
                           title="【DevOps】Backstage介绍及如何在Azure Kubernetes Service上进行部署" target="_blank">【DevOps】Backstage介绍及如何在Azure Kubernetes Service上进行部署</a>
                        <span class="text-muted">小涵</span>
<a class="tag" taget="_blank" href="/search/Azure%E4%BA%91%E4%BC%81%E4%B8%9A%E5%AE%9E%E8%B7%B5%E5%88%86%E4%BA%AB/1.htm">Azure云企业实践分享</a><a class="tag" taget="_blank" href="/search/devops/1.htm">devops</a><a class="tag" taget="_blank" href="/search/azure/1.htm">azure</a><a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/backstage/1.htm">backstage</a>
                        <div>【DevOps】Backstage介绍及如何在AzureKubernetesService上进行部署推荐超级课程:本地离线DeepSeekAI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录【DevOps】Backstage介绍及如何在AzureKubernetesService上进行部署Backstage介绍在AKS上部署Bac</div>
                    </li>
                    <li><a href="/article/1901409156108185600.htm"
                           title="kubernetes(K8S)学习(七):K8S之系统核心组件" target="_blank">kubernetes(K8S)学习(七):K8S之系统核心组件</a>
                        <span class="text-muted">꯭ 瞎꯭扯꯭蛋꯭</span>
<a class="tag" taget="_blank" href="/search/Kubernetes/1.htm">Kubernetes</a><a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a>
                        <div>K8S之系统核心组件K8s系统核心组件1.1Master和Node1.2kubeadm1.3先把核心组件总体过一遍1.4Kubernetes源码查看方式1.5kubectl1.6APIServer1.7集群安全机制之APIServer1.8Scheduler1.9kubelet1.10kube-proxyK8s系统核心组件1.1Master和Node官网:https://kubernetes.io</div>
                    </li>
                    <li><a href="/article/1901406253884698624.htm"
                           title="K8S之QoS详解" target="_blank">K8S之QoS详解</a>
                        <span class="text-muted">RedCong</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%91%E5%8E%9F%E7%94%9F/1.htm">云原生</a><a class="tag" taget="_blank" href="/search/k8s/1.htm">k8s</a><a class="tag" taget="_blank" href="/search/Openshift/1.htm">Openshift</a><a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/%E4%BA%91%E5%8E%9F%E7%94%9F/1.htm">云原生</a>
                        <div>PodQoS类服务质量(QualityofService,QoS)类,阐述Kubernetes如何根据为Pod中的容器指定的资源约束为每个Pod设置QoS类。Kubernetes依赖这种分类来决定当Node上没有足够可用资源时要驱逐哪些Pod。QoS类(QualityofServiceclasses)Kubernetes对你运行的Pod进行分类,并将每个Pod分配到特定的QoS类中。Kuberne</div>
                    </li>
                    <li><a href="/article/1901402596761989120.htm"
                           title="docker compose的使用" target="_blank">docker compose的使用</a>
                        <span class="text-muted">LCY133</span>
<a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>以下是关于DockerCompose的详细使用指南和核心功能解析:一、DockerCompose核心价值DockerCompose是用于定义和编排多容器应用的工具,通过YAML文件实现以下功能:•一键启停:用单条命令管理多个关联容器•环境隔离:为每个服务创建独立运行环境•依赖管理:自动处理服务启动顺序•配置复用:标准化开发/测试/生产环境二、完整使用流程1.安装DockerCompose#Linu</div>
                    </li>
                    <li><a href="/article/1901400322832658432.htm"
                           title="k8s系统学习路径" target="_blank">k8s系统学习路径</a>
                        <span class="text-muted">LCY133</span>
<a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a>
                        <div>学习Kubernetes(K8s)需要循序渐进,结合理论知识和实践操作。以下是学习Kubernetes的推荐步骤:1.先决条件•掌握容器基础:先学习Docker,理解容器化概念(镜像、容器、仓库)、Dockerfile编写和容器生命周期管理。•熟悉Linux基础:了解Linux命令行操作、网络、文件系统等。•了解云计算概念:如虚拟化、负载均衡、服务发现、分布式系统等。2.Kubernetes核心概</div>
                    </li>
                    <li><a href="/article/1901398809984954368.htm"
                           title="C#请求队列后台服务" target="_blank">C#请求队列后台服务</a>
                        <span class="text-muted">~请叫我小祸害~</span>
<a class="tag" taget="_blank" href="/search/.NET%2FC%23/1.htm">.NET/C#</a><a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a><a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>队列执行1、首先需要一个公共类里面有我们的队列需要执行的方法这个方法最好是一个单独的不受别的控制器影响的class。因为你如果声明错位置的话一不小心就会把我们的队列重置。导致队列内容丢失造成损失。大家如果有某些方法运行时间太长但又需要快速给出结果,就可以利用队列,我们这边直接给她结果。然后具体操作我们在内部慢慢执行。//比如说我这里新建一个Class专门用来存放这个方法和队列内容容器publicc</div>
                    </li>
                    <li><a href="/article/1901385181122588672.htm"
                           title="C++ list" target="_blank">C++ list</a>
                        <span class="text-muted">azaz_plus</span>
<a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a><a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a><a class="tag" taget="_blank" href="/search/STL/1.htm">STL</a><a class="tag" taget="_blank" href="/search/list/1.htm">list</a>
                        <div>1.std::list基本概念定义:std::list是C++标准库提供的带头(哨兵位)双向循环链表容器,支持高效的元素插入和删除。头文件:#include2.构造函数(1)默认构造函数listlist1;//创建一个空list,size=0(2)指定初始大小和默认值listlist2(5);//5个元素,默认初始化(int为0)listlist3(5,3.14);//5个元素,每个值为3.14(</div>
                    </li>
                    <li><a href="/article/1901366646497406976.htm"
                           title="harmony Next 基础知识点1" target="_blank">harmony Next 基础知识点1</a>
                        <span class="text-muted">趋势大仙</span>
<a class="tag" taget="_blank" href="/search/Harmony/1.htm">Harmony</a><a class="tag" taget="_blank" href="/search/harmonyos/1.htm">harmonyos</a><a class="tag" taget="_blank" href="/search/%E5%8D%8E%E4%B8%BA/1.htm">华为</a>
                        <div>容器类—Column和Row布局容器概念Column表示沿垂直方向布局的容器Row表示沿水平方向布局的容器对齐方式justifyContent:设置子元素在主轴方向的对齐格式alignItems:设置子元素在交叉轴方向的对齐格式主轴和交叉轴的概念主轴:在Column容器中的子组件是按照从上到下的垂直方向布局的,其主轴的方向是垂直方向;在Row容器中的组件是按照从左到右的水平方向布局的,其主轴的方向</div>
                    </li>
                    <li><a href="/article/1901358949681131520.htm"
                           title="kubernetes集群监控 Kube-Prometheus-Stack" target="_blank">kubernetes集群监控 Kube-Prometheus-Stack</a>
                        <span class="text-muted">xiaojinran</span>
<a class="tag" taget="_blank" href="/search/k8s/1.htm">k8s</a><a class="tag" taget="_blank" href="/search/prometheus/1.htm">prometheus</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/prometheus/1.htm">prometheus</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/grafana/1.htm">grafana</a>
                        <div>kubernetes集群监控概述Kubernetes(K8s)集群监控是指对Kubernetes集群中的各个组件和资源进行实时监测和数据收集,以获取对集群健康状态、性能指标和事件的可视化和告警。Kubernetes集群监控的内容通常包括以下几个方面:基础设施监控:监控物理服务器、虚拟机或云实例的资源使用情况,包括CPU、内存、磁盘和网络等指标。这可以帮助确保集群的底层基础设施正常运行,并及时发现资</div>
                    </li>
                    <li><a href="/article/1901342050364747776.htm"
                           title="kubeadm安装k8s v1.20集群" target="_blank">kubeadm安装k8s v1.20集群</a>
                        <span class="text-muted">小腿乱蹬~</span>
<a class="tag" taget="_blank" href="/search/k8s/1.htm">k8s</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/kubernetes/1.htm">kubernetes</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a>
                        <div>kubeadm安装kubernetesv1.20环境准备安装Docker安装kubeadm,kubectl,kubelet部署master向集群添加节点部署容器网络环境准备角色IPk8s-master172.16.10.50k8s-node1172.16.10.51k8s-node2172.16.10.52关闭防火墙:$systemctlstopfirewalld$systemctldisable</div>
                    </li>
                                <li><a href="/article/29.htm"
                                       title="SQL的各种连接查询" target="_blank">SQL的各种连接查询</a>
                                    <span class="text-muted">xieke90</span>
<a class="tag" taget="_blank" href="/search/UNION+ALL/1.htm">UNION ALL</a><a class="tag" taget="_blank" href="/search/UNION/1.htm">UNION</a><a class="tag" taget="_blank" href="/search/%E5%A4%96%E8%BF%9E%E6%8E%A5/1.htm">外连接</a><a class="tag" taget="_blank" href="/search/%E5%86%85%E8%BF%9E%E6%8E%A5/1.htm">内连接</a><a class="tag" taget="_blank" href="/search/JOIN/1.htm">JOIN</a>
                                    <div>一、内连接 
  概念:内连接就是使用比较运算符根据每个表共有的列的值匹配两个表中的行。 
                内连接(join 或者inner join ) 
      SQL语法: 
      select * fron</div>
                                </li>
                                <li><a href="/article/156.htm"
                                       title="java编程思想--复用类" target="_blank">java编程思想--复用类</a>
                                    <span class="text-muted">百合不是茶</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%BB%A7%E6%89%BF/1.htm">继承</a><a class="tag" taget="_blank" href="/search/%E4%BB%A3%E7%90%86/1.htm">代理</a><a class="tag" taget="_blank" href="/search/%E7%BB%84%E5%90%88/1.htm">组合</a><a class="tag" taget="_blank" href="/search/final%E7%B1%BB/1.htm">final类</a>
                                    <div>      复用类看着标题都不知道是什么,再加上java编程思想翻译的比价难懂,所以知道现在才看这本软件界的奇书 
  
一:组合语法:就是将对象的引用放到新类中即可 
    代码: 
    
package com.wj.reuse;

/**
 * 
 * @author Administrator 组</div>
                                </li>
                                <li><a href="/article/283.htm"
                                       title="[开源与生态系统]国产CPU的生态系统" target="_blank">[开源与生态系统]国产CPU的生态系统</a>
                                    <span class="text-muted">comsci</span>
<a class="tag" taget="_blank" href="/search/cpu/1.htm">cpu</a>
                                    <div> 
 
      计算机要从娃娃抓起...而孩子最喜欢玩游戏.... 
 
      要让国产CPU在国内市场形成自己的生态系统和产业链,国家和企业就不能够忘记游戏这个非常关键的环节.... 
 
      投入一些资金和资源,人力和政策,让游</div>
                                </li>
                                <li><a href="/article/410.htm"
                                       title="JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释" target="_blank">JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释</a>
                                    <span class="text-muted">商人shang</span>
<a class="tag" taget="_blank" href="/search/jvm%E5%86%85%E5%AD%98/1.htm">jvm内存</a>
                                    <div>jvm区域总体分两类,heap区和非heap区。heap区又分:Eden Space(伊甸园)、Survivor Space(幸存者区)、Tenured Gen(老年代-养老区)。 非heap区又分:Code Cache(代码缓存区)、Perm Gen(永久代)、Jvm Stack(java虚拟机栈)、Local Method Statck(本地方法栈)。 
HotSpot虚拟机GC算法采用分代收</div>
                                </li>
                                <li><a href="/article/537.htm"
                                       title="页面上调用 QQ" target="_blank">页面上调用 QQ</a>
                                    <span class="text-muted">oloz</span>
<a class="tag" taget="_blank" href="/search/qq/1.htm">qq</a>
                                    <div><A href="tencent://message/?uin=707321921&amp;Site=有事Q我&amp;Menu=yes">   
<img style="border:0px;" src=http://wpa.qq.com/pa?p=1:707321921:1></a></div>
                                </li>
                                <li><a href="/article/664.htm"
                                       title="一些问题" target="_blank">一些问题</a>
                                    <span class="text-muted">文强chu</span>
<a class="tag" taget="_blank" href="/search/%E9%97%AE%E9%A2%98/1.htm">问题</a>
                                    <div>1.eclipse 导出 doc  出现“The Javadoc command does not exist.” javadoc command 选择 jdk/bin/javadoc.exe 2.tomcate 配置 web 项目 ..... 
SQL:3.mysql  * 必须得放前面 否则  select&nbs</div>
                                </li>
                                <li><a href="/article/791.htm"
                                       title="生活没有安全感" target="_blank">生活没有安全感</a>
                                    <span class="text-muted">小桔子</span>
<a class="tag" taget="_blank" href="/search/%E7%94%9F%E6%B4%BB/1.htm">生活</a><a class="tag" taget="_blank" href="/search/%E5%AD%A4%E7%8B%AC/1.htm">孤独</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%85%A8%E6%84%9F/1.htm">安全感</a>
                                    <div>       圈子好小,身边朋友没几个,交心的更是少之又少。在深圳,除了男朋友,没几个亲密的人。不知不觉男朋友成了唯一的依靠,毫不夸张的说,业余生活的全部。现在感情好,也很幸福的。但是说不准难免人心会变嘛,不发生什么大家都乐融融,发生什么很难处理。我想说如果不幸被分手(无论原因如何),生活难免变化很大,在深圳,我没交心的朋友。明</div>
                                </li>
                                <li><a href="/article/918.htm"
                                       title="php 基础语法" target="_blank">php 基础语法</a>
                                    <span class="text-muted">aichenglong</span>
<a class="tag" taget="_blank" href="/search/php+%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95/1.htm">php 基本语法</a>
                                    <div>1 .1 php变量必须以$开头 
<?php 
$a=” b”; 
echo 
?> 
1 .2 php基本数据库类型 Integer  float/double Boolean string 
1 .3 复合数据类型 数组array和对象 object 
1 .4 特殊数据类型  null 资源类型(resource)    $co</div>
                                </li>
                                <li><a href="/article/1045.htm"
                                       title="mybatis tools 配置详解" target="_blank">mybatis tools 配置详解</a>
                                    <span class="text-muted">AILIKES</span>
<a class="tag" taget="_blank" href="/search/mybatis/1.htm">mybatis</a>
                                    <div>MyBatis Generator中文文档 
MyBatis Generator中文文档地址: 
 
 http://generator.sturgeon.mopaas.com/ 
 
该中文文档由于尽可能和原文内容一致,所以有些地方如果不熟悉,看中文版的文档的也会有一定的障碍,所以本章根据该中文文档以及实际应用,使用通俗的语言来讲解详细的配置。 
本文使用Markdown进行编辑,但是博客显示效</div>
                                </li>
                                <li><a href="/article/1172.htm"
                                       title="继承与多态的探讨" target="_blank">继承与多态的探讨</a>
                                    <span class="text-muted">百合不是茶</span>
<a class="tag" taget="_blank" href="/search/JAVA%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1+%E7%BB%A7%E6%89%BF+%E5%AF%B9%E8%B1%A1/1.htm">JAVA面向对象 继承 对象</a>
                                    <div>继承 extends   多态 
继承是面向对象最经常使用的特征之一:继承语法是通过继承发、基类的域和方法 //继承就是从现有的类中生成一个新的类,这个新类拥有现有类的所有extends是使用继承的关键字: 
  
  
在A类中定义属性和方法; 
class A{
//定义属性
int age;
//定义方法
public void go</div>
                                </li>
                                <li><a href="/article/1299.htm"
                                       title="JS的undefined与null的实例" target="_blank">JS的undefined与null的实例</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a>
                                    <div><form name="theform" id="theform">
</form>

<script language="javascript">
    var a
    alert(typeof(b));    //这里提示undefined
    if(theform.datas</div>
                                </li>
                                <li><a href="/article/1426.htm"
                                       title="TDD实践(一)" target="_blank">TDD实践(一)</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%95%8F%E6%8D%B7/1.htm">敏捷</a><a class="tag" taget="_blank" href="/search/TDD/1.htm">TDD</a>
                                    <div>一.TDD概述 
        TDD:测试驱动开发,它的基本思想就是在开发功能代码之前,先编写测试代码。也就是说在明确要开发某个功能后,首先思考如何对这个功能进行测试,并完成测试代码的编写,然后编写相关的代码满足这些测试用例。然后循环进行添加其他功能,直到完全部功能的开发。 
    </div>
                                </li>
                                <li><a href="/article/1553.htm"
                                       title="[Maven学习笔记十]Maven Profile与资源文件过滤器" target="_blank">[Maven学习笔记十]Maven Profile与资源文件过滤器</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a>
                                    <div>什么是Maven Profile 
Maven Profile的含义是针对编译打包环境和编译打包目的配置定制,可以在不同的环境上选择相应的配置,例如DB信息,可以根据是为开发环境编译打包,还是为生产环境编译打包,动态的选择正确的DB配置信息 
  
Profile的激活机制 
1.Profile可以手工激活,比如在Intellij Idea的Maven Project视图中可以选择一个P</div>
                                </li>
                                <li><a href="/article/1680.htm"
                                       title="【Hive八】Hive用户自定义生成表函数(UDTF)" target="_blank">【Hive八】Hive用户自定义生成表函数(UDTF)</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/hive/1.htm">hive</a>
                                    <div>1. 什么是UDTF 
  
UDTF,是User Defined Table-Generating Functions,一眼看上去,貌似是用户自定义生成表函数,这个生成表不应该理解为生成了一个HQL Table, 貌似更应该理解为生成了类似关系表的二维行数据集 
  2. 如何实现UDTF 
 
 继承org.apache.hadoop.hive.ql.udf.generic</div>
                                </li>
                                <li><a href="/article/1807.htm"
                                       title="tfs restful api 加auth 2.0认计" target="_blank">tfs restful api 加auth 2.0认计</a>
                                    <span class="text-muted">ronin47</span>

                                    <div>  目前思考如何给tfs的ngx-tfs api增加安全性。有如下两点: 
  一是基于客户端的ip设置。这个比较容易实现。 
  二是基于OAuth2.0认证,这个需要lua,实现起来相对于一来说,有些难度。 
  现在重点介绍第二种方法实现思路。 
   
前言:我们使用Nginx的Lua中间件建立了OAuth2认证和授权层。如果你也有此打算,阅读下面的文档,实现自动化并获得收益。SeatGe</div>
                                </li>
                                <li><a href="/article/1934.htm"
                                       title="jdk环境变量配置" target="_blank">jdk环境变量配置</a>
                                    <span class="text-muted">byalias</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/jdk/1.htm">jdk</a>
                                    <div>进行java开发,首先要安装jdk,安装了jdk后还要进行环境变量配置: 
 
1、下载jdk(http://java.sun.com/javase/downloads/index.jsp),我下载的版本是:jdk-7u79-windows-x64.exe 
 
2、安装jdk-7u79-windows-x64.exe 
 
3、配置环境变量:右击"计算机"-->&quo</div>
                                </li>
                                <li><a href="/article/2061.htm"
                                       title="《代码大全》表驱动法-Table Driven Approach-2" target="_blank">《代码大全》表驱动法-Table Driven Approach-2</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>package com.ljn.base;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.uti</div>
                                </li>
                                <li><a href="/article/2188.htm"
                                       title="SQL 数值四舍五入 小数点后保留2位" target="_blank">SQL 数值四舍五入 小数点后保留2位</a>
                                    <span class="text-muted">chicony</span>
<a class="tag" taget="_blank" href="/search/%E5%9B%9B%E8%88%8D%E4%BA%94%E5%85%A5/1.htm">四舍五入</a>
                                    <div>  
1.round() 函数是四舍五入用,第一个参数是我们要被操作的数据,第二个参数是设置我们四舍五入之后小数点后显示几位。 
2.numeric 函数的2个参数,第一个表示数据长度,第二个参数表示小数点后位数。 
例如: 
  select   cast(round(12.5,2)   as   numeric(5,2))  </div>
                                </li>
                                <li><a href="/article/2315.htm"
                                       title="c++运算符重载" target="_blank">c++运算符重载</a>
                                    <span class="text-muted">CrazyMizzz</span>
<a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a>
                                    <div>一、加+,减-,乘*,除/ 的运算符重载 
 
Rational operator*(const Rational &x) const{ 
 return Rational(x.a * this->a); 
 } 
在这里只写乘法的,加减除的写法类似 
 
二、<<输出,>>输入的运算符重载 
     &nb</div>
                                </li>
                                <li><a href="/article/2442.htm"
                                       title="hive DDL语法汇总" target="_blank">hive DDL语法汇总</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/hive/1.htm">hive</a><a class="tag" taget="_blank" href="/search/%E4%BF%AE%E6%94%B9%E5%88%97/1.htm">修改列</a><a class="tag" taget="_blank" href="/search/DDL/1.htm">DDL</a><a class="tag" taget="_blank" href="/search/%E4%BF%AE%E6%94%B9%E8%A1%A8/1.htm">修改表</a>
                                    <div>hive DDL语法汇总 
1、对表重命名 
hive> ALTER TABLE table_name RENAME TO new_table_name; 
  
2、修改表备注 
hive> ALTER TABLE table_name SET TBLPROPERTIES ('comment' = new_comm</div>
                                </li>
                                <li><a href="/article/2569.htm"
                                       title="jbox使用说明" target="_blank">jbox使用说明</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a>
                                    <div>参考网址:http://www.kudystudio.com/jbox/jbox-demo.html   jBox v2.3 beta    [ 
点击下载]  
 
技术交流QQGroup:172543951 100521167   
 
 [2011-11-11] jBox v2.3 正式版 
 - [调整&修复] IE6下有iframe或页面有active、applet控件</div>
                                </li>
                                <li><a href="/article/2696.htm"
                                       title="UISegmentedControl 开发笔记" target="_blank">UISegmentedControl 开发笔记</a>
                                    <span class="text-muted">dcj3sjt126com</span>

                                    <div>  //    typedef NS_ENUM(NSInteger, UISegmentedControlStyle) { 
    //        UISegmentedControlStylePlain,     // large plain 
  &</div>
                                </li>
                                <li><a href="/article/2823.htm"
                                       title="Slick生成表映射文件" target="_blank">Slick生成表映射文件</a>
                                    <span class="text-muted">ekian</span>
<a class="tag" taget="_blank" href="/search/scala/1.htm">scala</a>
                                    <div>Scala添加SLICK进行数据库操作,需在sbt文件上添加slick-codegen包 
 
"com.typesafe.slick"    %% "slick-codegen"      % slickVersion 
因为我是连接SQL Server数据库,还需添加slick-extensions,jtds包 
 

"com.typesa</div>
                                </li>
                                <li><a href="/article/2950.htm"
                                       title="ES-TEST" target="_blank">ES-TEST</a>
                                    <span class="text-muted">gengzg</span>
<a class="tag" taget="_blank" href="/search/test/1.htm">test</a>
                                    <div>package com.MarkNum;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation</div>
                                </li>
                                <li><a href="/article/3077.htm"
                                       title="为何外键不再推荐使用" target="_blank">为何外键不再推荐使用</a>
                                    <span class="text-muted">hugh.wang</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/DB/1.htm">DB</a>
                                    <div>表的关联,是一种逻辑关系,并不需要进行物理上的“硬关联”,而且你所期望的关联,其实只是其数据上存在一定的联系而已,而这种联系实际上是在设计之初就定义好的固有逻辑。 
 
在业务代码中实现的时候,只要按照设计之初的这种固有关联逻辑来处理数据即可,并不需要在数据库层面进行“硬关联”,因为在数据库层面通过使用外键的方式进行“硬关联”,会带来很多额外的资源消耗来进行一致性和完整性校验,即使很多时候我们并不</div>
                                </li>
                                <li><a href="/article/3204.htm"
                                       title="领域驱动设计" target="_blank">领域驱动设计</a>
                                    <span class="text-muted">julyflame</span>
<a class="tag" taget="_blank" href="/search/VO/1.htm">VO</a><a class="tag" taget="_blank" href="/search/DAO/1.htm">DAO</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a><a class="tag" taget="_blank" href="/search/DTO/1.htm">DTO</a><a class="tag" taget="_blank" href="/search/po/1.htm">po</a>
                                    <div>概念: 
 
VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。 
 
DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对</div>
                                </li>
                                <li><a href="/article/3331.htm"
                                       title="单例设计模式" target="_blank">单例设计模式</a>
                                    <span class="text-muted">hm4123660</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/Singleton/1.htm">Singleton</a><a class="tag" taget="_blank" href="/search/%E5%8D%95%E4%BE%8B%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">单例设计模式</a><a class="tag" taget="_blank" href="/search/%E6%87%92%E6%B1%89%E5%BC%8F/1.htm">懒汉式</a><a class="tag" taget="_blank" href="/search/%E9%A5%BF%E6%B1%89%E5%BC%8F/1.htm">饿汉式</a>
                                    <div>       单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。 
     &nb</div>
                                </li>
                                <li><a href="/article/3458.htm"
                                       title="logback" target="_blank">logback</a>
                                    <span class="text-muted">zhb8015</span>
<a class="tag" taget="_blank" href="/search/log/1.htm">log</a><a class="tag" taget="_blank" href="/search/logback/1.htm">logback</a>
                                    <div>一、logback的介绍 
     Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback- classic和logback-access。logback-core是其它两个模块的基础模块。logback-classic是log4j的一个 改良版本。此外logback-class</div>
                                </li>
                                <li><a href="/article/3585.htm"
                                       title="整合Kafka到Spark Streaming——代码示例和挑战" target="_blank">整合Kafka到Spark Streaming——代码示例和挑战</a>
                                    <span class="text-muted">Stark_Summer</span>
<a class="tag" taget="_blank" href="/search/spark/1.htm">spark</a><a class="tag" taget="_blank" href="/search/storm/1.htm">storm</a><a class="tag" taget="_blank" href="/search/zookeeper/1.htm">zookeeper</a><a class="tag" taget="_blank" href="/search/PARALLELISM/1.htm">PARALLELISM</a><a class="tag" taget="_blank" href="/search/processing/1.htm">processing</a>
                                    <div>作者Michael G. Noll是瑞士的一位工程师和研究员,效力于Verisign,是Verisign实验室的大规模数据分析基础设施(基础Hadoop)的技术主管。本文,Michael详细的演示了如何将Kafka整合到Spark Streaming中。 期间, Michael还提到了将Kafka整合到 Spark Streaming中的一些现状,非常值得阅读,虽然有一些信息在Spark 1.2版</div>
                                </li>
                                <li><a href="/article/3712.htm"
                                       title="spring-master-slave-commondao" target="_blank">spring-master-slave-commondao</a>
                                    <span class="text-muted">王新春</span>
<a class="tag" taget="_blank" href="/search/DAO/1.htm">DAO</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/dataSource/1.htm">dataSource</a><a class="tag" taget="_blank" href="/search/slave/1.htm">slave</a><a class="tag" taget="_blank" href="/search/master/1.htm">master</a>
                                    <div>互联网的web项目,都有个特点:请求的并发量高,其中请求最耗时的db操作,又是系统优化的重中之重。 
 
为此,往往搭建 db的 一主多从库的 数据库架构。作为web的DAO层,要保证针对主库进行写操作,对多个从库进行读操作。当然在一些请求中,为了避免主从复制的延迟导致的数据不一致性,部分的读操作也要到主库上。(这种需求一般通过业务垂直分开,比如下单业务的代码所部署的机器,读去应该也要从主库读取数</div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html>