主頁 > 軟體設計 > 實戰:Containerd高級命令列工具nerdctl安裝及使用-20211025

實戰:Containerd高級命令列工具nerdctl安裝及使用-20211025

2021-10-27 16:38:43 軟體設計

image-20211025165147981

目錄

文章目錄

    • 目錄
    • 實驗環境
    • 實驗軟體
    • nerdctl安裝
    • 0、nerd幫助命令
    • 1、Run&Exec ?
      • 🐳nerdctl run
      • **🐳nerdctl exec**
    • 2、容器管理
      • **🐳nerdctl ps**:列出容器
      • **🐳nerdctl inspect**:獲取容器的詳細資訊,
      • **🐳nerdctl logs**:獲取容器日志
      • **🐳nerdctl stop**:停止容器
      • **🐳nerdctl rm**:洗掉容器
    • 3、鏡像管理
      • **🐳nerdctl images**:鏡像串列
      • **🐳nerdctl pull**:拉取鏡像
      • **🐳nerdctl push**:推送鏡像
      • **🐳nerdctl tag**:鏡像標簽
      • **🐳nerdctl save**:匯出鏡像
      • **🐳nerdctl rmi**:洗掉鏡像
      • **🐳nerdctl load**:匯入鏡像
    • 4、鏡像構建
      • **🐳nerdctl build**:從 Dockerfile 構建鏡像
    • 需要注意的問題
      • :question:(待解決)nerdctl run命令創建出的容器在宿主機上看不到埠號,奇怪
      • :question:(待解決)還有個奇怪的問題就是:容器名被占用問題,,,
      • :heavy_check_mark:(已解決)nerdctl為啥沒有自動補全呢?
      • :heavy_check_mark:注意:不推薦使用commit去構建物件,而是要用build去構建物件
      • :heavy_check_mark:注意:用build構建鏡像時,下面這個.問題,
      • :heavy_check_mark:注意:containerd網路,它對接的是cni
      • :heavy_check_mark:注意:nerdctl在構建鏡像時可以配置.dockerignore檔案的,
    • 關于我
    • 總結

實驗環境

實驗環境:
1、win10筆記本
2、1臺centos7.6虛機(vmwrokstation虛機)
	cri-containerd-cni-1.5.5-linux-amd64.tar.gz
	nerdctl-0.12.1-linux-amd64.tar.gz

實驗軟體

鏈接:https://pan.baidu.com/s/1Im37YWoOibJ009hEAD_HBQ
提取碼:jiik
–來自百度網盤超級會員V6的分享

nerdctl-0.12.1-linux-amd64.tar.gz、buildkit-v0.9.1.linux-amd64.tar.gz

nerdctl安裝

同樣直接在 GitHub Release 頁面下載對應的壓縮包解壓到 PATH 路徑下即可:

https://github.com/containerd/nerdctl

image-20211025131157048

image-20211025131227572

下載nerdctl-0.12.1-linux-amd64.tar.gz軟體包:

# 如果沒有安裝 containerd,則可以下載 nerdctl-full-<VERSION>-linux-amd64.tar.gz 包進行安裝
?  ~ wget https://github.com/containerd/nerdctl/releases/download/v0.12.1/nerdctl-0.12.1-linux-amd64.tar.gz

# 如果有限制,也可以替換成下面的 URL 加速下載
[root@containerd ~]#wget https://download.fastgit.org/containerd/nerdctl/releases/download/v0.12.1/nerdctl-0.12.1-linux-amd64.tar.gz
--2021-10-25 13:13:43--  https://download.fastgit.org/containerd/nerdctl/releases/download/v0.12.1/nerdctl-0.12.1-linux-amd64.tar.gz
Resolving download.fastgit.org (download.fastgit.org)... 88.198.10.254
Connecting to download.fastgit.org (download.fastgit.org)|88.198.10.254|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7528755 (7.2M) [application/octet-stream]
Saving to: ‘nerdctl-0.12.1-linux-amd64.tar.gz’

100%[===============================================================================================================================>] 7,528,755   3.31MB/s   in 2.2s

2021-10-25 13:13:46 (3.31 MB/s) - ‘nerdctl-0.12.1-linux-amd64.tar.gz’ saved [7528755/7528755][root@containerd ~]#ll -h nerdctl-0.12.1-linux-amd64.tar.gz
-rw-r--r-- 1 root root 7.2M Oct  5 15:10 nerdctl-0.12.1-linux-amd64.tar.gz
[root@containerd ~]#

解壓軟體包到相應目錄:

[root@containerd ~]#tar tf nerdctl-0.12.1-linux-amd64.tar.gz #先查看下壓縮包檔案內容
nerdctl
containerd-rootless-setuptool.sh
containerd-rootless.sh
[root@containerd ~]#mkdir -p /usr/local/containerd/bin  && tar -zxvf nerdctl-0.12.1-linux-amd64.tar.gz nerdctl && mv nerdctl /usr/local/containerd/bin
nerdctl
[root@containerd ~]#ln -s /usr/local/containerd/bin/nerdctl /usr/bin/nerdctl

驗證:

[root@containerd ~]#nerdctl version
Client:
 Version:       v0.12.1
 Git commit:    6f0c8b7bc63270404c9f5810a899e6bae7546608

Server:
 containerd:
  Version:      v1.5.5
  GitCommit:    72cec4be58a9eb6b2910f5d10f1c01ca47d231c0
[root@containerd ~]#

至此,nerdctl安裝完成,

安裝完成后接下來學習下 nerdctl 命令列工具的使用,

0、nerd幫助命令

[root@containerd ~]#nerdctl
NAME:
   nerdctl - Docker-compatible CLI for containerd

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

VERSION:
   0.12.1

COMMANDS:
   run         Run a command in a new container
   exec        Run a command in a running container
   ps          List containers
   logs        Fetch the logs of a container. Currently, only containers created with `nerdctl run -d` are supported.
   port        List port mappings or a specific mapping for the container
   stop        Stop one or more running containers
   start       Start one or more running containers
   kill        Kill one or more running containers
   rm          Remove one or more containers
   pause       Pause all processes within one or more containers
   unpause     Unpause all processes within one or more containers
   commit      [flags] CONTAINER REPOSITORY[:TAG]
   wait        Block until one or more containers stop, then print their exit codes.
   build       Build an image from a Dockerfile. Needs buildkitd to be running.
   images      List images
   pull        Pull an image from a registry
   push        Push an image or a repository to a registry
   load        Load an image from a tar archive or STDIN
   save        Save one or more images to a tar archive (streamed to STDOUT by default)
   tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
   rmi         Remove one or more images
   events      Get real time events from the server
   info        Display system-wide information
   version     Show the nerdctl version information
   inspect     Return low-level information on objects.
   top         Display the running processes of a container
   login       Log in to a Docker registry
   logout      Log out from a Docker registry
   compose     Compose
   completion  Show shell completion
   help, h     Shows a list of commands or help for one command
   Management:
     container  Manage containers
     image      Manage images
     network    Manage networks
     volume     Manage volumes
     system     Manage containerd
     namespace  Manage containerd namespaces

GLOBAL OPTIONS:
   --debug                                            debug mode (default: false)
   --debug-full                                       debug mode (with full output) (default: false)
   --address value, -a value, --host value, -H value  containerd address, optionally with "unix://" prefix (default: "/run/containerd/containerd.sock") [$CONTAINERD_ADDRESS]
   --namespace value, -n value                        containerd namespace, such as "moby" for Docker, "k8s.io" for Kubernetes (default: "default") [$CONTAINERD_NAMESPACE]
   --snapshotter value, --storage-driver value        containerd snapshotter (default: "overlayfs") [$CONTAINERD_SNAPSHOTTER]
   --cni-path value                                   Set the cni-plugins binary directory (default: "/opt/cni/bin") [$CNI_PATH]
   --cni-netconfpath value                            Set the CNI config directory (default: "/etc/cni/net.d") [$NETCONFPATH]
   --data-root value                                  Root directory of persistent nerdctl state (managed by nerdctl, not by containerd) (default: "/var/lib/nerdctl")
   --cgroup-manager value                             Cgroup manager to use ("cgroupfs"|"systemd") (default: "cgroupfs")
   --insecure-registry                                skips verifying HTTPS certs, and allows falling back to plain HTTP (default: false)
   --help, -h                                         show help (default: false)
   --version, -v                                      print the version (default: false)
[root@containerd ~]#

1、Run&Exec ?

🐳nerdctl run

docker run 類似可以使用 nerdctl run 命令運行容器,例如:

?  ~ nerdctl run -d -p 80:80 --name=nginx --restart=always nginx:alpine
docker.io/library/nginx:alpine:                                                   resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:bead42240255ae1485653a956ef41c9e458eb077fcb6dc664cbc3aa9701a05ce:    done           |++++++++++++++++++++++++++++++++++++++| manifest-sha256:ce6ca11a3fa7e0e6b44813901e3289212fc2f327ee8b1366176666e8fb470f24: done           |++++++++++++++++++++++++++++++++++++++| config-sha256:7ce0143dee376bfd2937b499a46fb110bda3c629c195b84b1cf6e19be1a9e23b:   done           |++++++++++++++++++++++++++++++++++++++| elapsed: 5.3 s                                                                    total:  3.1 Ki (606.0 B/s)                                       6e489777d2f73dda8a310cdf8da9df38353c1aa2021d3c2270b30eff1806bcf8

可選的引數使用和 docker run 基本一直,比如 -i-t--cpus--memory 等選項,可以使用 nerdctl run --help 獲取可使用的命令選項:

[root@containerd ~]#nerdctl run --help
NAME:
   nerdctl run - Run a command in a new container

USAGE:
   nerdctl run [command options] [arguments...]

OPTIONS:
   --help                        show help (default: false)
   --tty, -t                     (Currently -t needs to correspond to -i) (default: false)
   --interactive, -i             Keep STDIN open even if not attached (default: false)
   --detach, -d                  Run container in background and print container ID (default: false)
   --restart value               Restart policy to apply when a container exits (implemented values: "no"|"always") (default: "no")
   --rm                          Automatically remove the container when it exits (default: false)
   --pull value                  Pull image before running ("always"|"missing"|"never") (default: "missing")
   --network value, --net value  Connect a container to a network ("bridge"|"host"|"none") (default: "bridge")
   --dns value                   Set custom DNS servers
   --publish value, -p value     Publish a container's port(s) to the host
   --hostname value, -h value    Container host name
   --cpus value                  Number of CPUs (default: 0)
   --memory value, -m value      Memory limit
   --pid value                   PID namespace to use
   --pids-limit value            Tune container pids limit (set -1 for unlimited) (default: -1)
   --cgroupns value              Cgroup namespace to use, the default depends on the cgroup version ("host"|"private") (default: "host")
   --cpuset-cpus value           CPUs in which to allow execution (0-3, 0,1)
   --cpu-shares value            CPU shares (relative weight) (default: 0)
   --device value                Add a host device to the container
   --user value, -u value        Username or UID (format: <name|uid>[:<group|gid>])
   --security-opt value          Security options
   --cap-add value               Add Linux capabilities
   --cap-drop value              Drop Linux capabilities
   --privileged                  Give extended privileges to this container (default: false)
   --runtime value               Runtime to use for this container, e.g. "crun", or "io.containerd.runsc.v1" (default: "io.containerd.runc.v2")
   --sysctl value                Sysctl options
   --gpus value                  GPU devices to add to the container ('all' to pass all GPUs)
   --volume value, -v value      Bind mount a volume
   --read-only                   Mount the container's root filesystem as read only (default: false)
   --rootfs                      The first argument is not an image but the rootfs to the exploded container (default: false)
   --entrypoint value            Overwrite the default ENTRYPOINT of the image
   --workdir value, -w value     Working directory inside the container
   --env value, -e value         Set environment variables
   --add-host value              Add a custom host-to-IP mapping (host:ip)
   --env-file value              Set environment variables from file
   --name value                  Assign a name to the container
   --label value, -l value       Set meta data on a container
   --label-file value            Read in a line delimited file of labels
   --cidfile value               Write the container ID to the file
   --shm-size value              Size of /dev/shm
   --pidfile value               file path to write the task's pid
   --ulimit value                Ulimit options

[root@containerd ~]#

🐳nerdctl exec

同樣也可以使用 exec 命令執行容器相關命令,例如:

?  ~ nerdctl exec -it nginx /bin/sh
/ # date
Thu Aug 19 06:43:19 UTC 2021
/ #

2、容器管理

🐳nerdctl ps:列出容器

使用 nerdctl ps 命令可以列出所有容器,

?  ~ nerdctl ps
CONTAINER ID    IMAGE                             COMMAND                   CREATED           STATUS    PORTS                 NAMES
6e489777d2f7    docker.io/library/nginx:alpine    "/docker-entrypoint.…"    10 minutes ago    Up        0.0.0.0:80->80/tcp    nginx

同樣可以使用 -a 選項顯示所有的容器串列,默認只顯示正在運行的容器,不過需要注意的是 nerdctl ps 命令并沒有實作 docker ps 下面的 --filter--format--last--size 等選項,

image-20211025152246786

🐳nerdctl inspect:獲取容器的詳細資訊,

?  ~ nerdctl inspect nginx
[
    {
        "Id": "6e489777d2f73dda8a310cdf8da9df38353c1aa2021d3c2270b30eff1806bcf8",
        "Created": "2021-08-19T06:35:46.403464674Z",
        "Path": "/docker-entrypoint.sh",
        "Args": [
            "nginx",
            "-g",
            "daemon off;"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Pid": 2002,
            "ExitCode": 0,
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "docker.io/library/nginx:alpine",
        "ResolvConfPath": "/var/lib/nerdctl/1935db59/containers/default/6e489777d2f73dda8a310cdf8da9df38353c1aa2021d3c2270b30eff1806bcf8/resolv.conf",
        "LogPath": "/var/lib/nerdctl/1935db59/containers/default/6e489777d2f73dda8a310cdf8da9df38353c1aa2021d3c2270b30eff1806bcf8/6e489777d2f73dda8a310cdf8da9df38353c1aa2021d3c2270b30eff1806bcf8-json.log",
        "Name": "nginx",
        "Driver": "overlayfs",
        "Platform": "linux",
        "AppArmorProfile": "nerdctl-default",
        "NetworkSettings": {
            "Ports": {
                "80/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "80"
                    }
                ]
            },
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "10.4.0.3",
            "IPPrefixLen": 24,
            "MacAddress": "f2:b1:8e:a2:fe:18",
            "Networks": {
                "unknown-eth0": {
                    "IPAddress": "10.4.0.3",
                    "IPPrefixLen": 24,
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "f2:b1:8e:a2:fe:18"
                }
            }
        }
    }
]

可以看到顯示結果和 docker inspect 也基本一致的,

🐳nerdctl logs:獲取容器日志

查看容器日志是我們平時經常會使用到的一個功能,同樣我們可以使用 nerdctl logs 來獲取日志資料:

?  ~ nerdctl logs -f nginx
......
2021/08/19 06:35:46 [notice] 1#1: start worker processes
2021/08/19 06:35:46 [notice] 1#1: start worker process 32
2021/08/19 06:35:46 [notice] 1#1: start worker process 33

同樣支持 -f-t-n--since--until 這些選項,

#-n選項:
[root@containerd ~]#nerdctl logs -n 3 nginx_bak
2021/10/24 23:17:40 [notice] 1#1: start worker process 32
2021/10/24 23:17:40 [notice] 1#1: start worker process 33
10.4.0.1 - - [24/Oct/2021:23:42:57 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
[root@containerd ~]#

🐳nerdctl stop:停止容器

?  ~ nerdctl stop nginx
nginx
?  ~ nerdctl ps
CONTAINER ID    IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES
?  ~ nerdctl ps -a
CONTAINER ID    IMAGE                             COMMAND                   CREATED           STATUS    PORTS                 NAMES
6e489777d2f7    docker.io/library/nginx:alpine    "/docker-entrypoint.…"    20 minutes ago    Up        0.0.0.0:80->80/tcp    nginx

🐳nerdctl rm:洗掉容器

?  ~ nerdctl rm nginx
You cannot remove a running container f4ac170235595f28bf962bad68aa81b20fc83b741751e7f3355bd77d8016462d. Stop the container before attempting removal or force remove
?  ~ nerdctl rm -f ginx
nginx
?  ~ nerdctl ps
CONTAINER ID    IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES

要強制洗掉同樣可以使用 -f--force 選項來操作,

3、鏡像管理

🐳nerdctl images:鏡像串列

?  ~ nerdctl images
REPOSITORY    TAG       IMAGE ID        CREATED           SIZE
alpine        latest    eb3e4e175ba6    6 days ago        5.9 MiB
nginx         alpine    bead42240255    29 minutes ago    16.0 KiB

也需要注意的是沒有實作 docker images 的一些選項,比如 --all--digests--filter--format

nerdctl images 和 ctr i ls的對比,nerctl更友好:

[root@containerd ~]#nerdctl images
REPOSITORY    TAG       IMAGE ID        CREATED         SIZE
nginx         alpine    686aac2769fd    38 hours ago    24.9 MiB
[root@containerd ~]#ctr i ls
REF                            TYPE                                                      DIGEST                                                                  SIZE    PLATFORMS                                                                                LABELS
docker.io/library/nginx:alpine application/vnd.docker.distribution.manifest.list.v2+json sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3 9.5 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
[root@containerd ~]#

🐳nerdctl pull:拉取鏡像

[root@containerd ~]#nerdctl images
REPOSITORY    TAG       IMAGE ID        CREATED         SIZE
nginx         alpine    686aac2769fd    38 hours ago    24.9 MiB
[root@containerd ~]#nerdctl pull busybox #nerdctl很優秀,可以直接接鏡像名的,而不像ctr命令那樣繁瑣,
docker.io/library/busybox:latest:                                                 resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:f7ca5a32c10d51aeda3b4d01c61c6061f497893d7f6628b92f822f7117182a57:    done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:febcf61cd6e1ac9628f6ac14fa40836d16f3c6ddef3b303ff0321606e55ddd0b: done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:16ea53ea7c652456803632d67517b78a4f9075a10bfdc4fc6b7b4cbf2bc98497:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:24fb2886d6f6c5d16481dd7608b47e78a8e92a13d6e64d87d57cb16d5f766d63:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 5.9 s                                                                    total:  753.5  (127.7 KiB/s)                       
[root@containerd ~]#nerdctl images
REPOSITORY    TAG       IMAGE ID        CREATED          SIZE
busybox       latest    f7ca5a32c10d    2 seconds ago    1.2 MiB
nginx         alpine    686aac2769fd    38 hours ago     24.9 MiB
[root@containerd ~]#

🐳nerdctl push:推送鏡像

當然在推送鏡像之前也可以使用 nerdctl login 命令登錄到鏡像倉庫,然后再執行 push 操作,

可以使用 nerdctl login --username xxx --password xxx 進行登錄,使用 nerdctl logout 可以注銷退出登錄,

[root@containerd ~]#nerdctl push harbor.k8s.local/course/nginx:alpine

[root@containerd ~]#nerdctl login --username xxx --password xxx harbor.k8s.local

[root@containerd ~]#nerdctl logout
Removing login credentials for https://index.docker.io/v1/
[root@containerd ~]#

🐳nerdctl tag:鏡像標簽

使用 tag 命令可以為一個鏡像創建一個別名鏡像:

?  ~ nerdctl images
REPOSITORY    TAG                  IMAGE ID        CREATED           SIZE
busybox       latest               0f354ec1728d    6 minutes ago     1.3 MiB
nginx         alpine               bead42240255    41 minutes ago    16.0 KiB
?  ~ nerdctl tag nginx:alpine harbor.k8s.local/course/nginx:alpine
?  ~ nerdctl images
REPOSITORY                       TAG                  IMAGE ID        CREATED           SIZE
busybox                          latest               0f354ec1728d    7 minutes ago     1.3 MiB
nginx                            alpine               bead42240255    41 minutes ago    16.0 KiB
harbor.k8s.local/course/nginx    alpine               bead42240255    2 seconds ago     16.0 KiB

注意:用tag打的鏡像,其Image ID都是相同的:

image-20211025101448781

🐳nerdctl save:匯出鏡像

使用 save 命令可以匯出鏡像為一個 tar 壓縮包,

?  ~ nerdctl save -o busybox.tar.gz busybox:latest
?  ~ ls -lh busybox.tar.gz
-rw-r--r-- 1 root root 761K Aug 19 15:19 busybox.tar.gz

🐳nerdctl rmi:洗掉鏡像

?  ~ nerdctl rmi busybox
Untagged: docker.io/library/busybox:latest@sha256:0f354ec1728d9ff32edcd7d1b8bbdfc798277ad36120dc3dc683be44524c8b60
Deleted: sha256:5b8c72934dfc08c7d2bd707e93197550f06c0751023dabb3a045b723c5e7b373

🐳nerdctl load:匯入鏡像

使用 load 命令可以將上面匯出的鏡像再次匯入:

?  ~ nerdctl load -i busybox.tar.gz
unpacking docker.io/library/busybox:latest (sha256:0f354ec1728d9ff32edcd7d1b8bbdfc798277ad36120dc3dc683be44524c8b60)...done

使用 -i--input 選項指定需要匯入的壓縮包,

4、鏡像構建

鏡像構建是平時我們非常重要的一個需求,我們知道 ctr 并沒有構建鏡像的命令,而現在我們又不使用 Docker 了,那么如何進行鏡像構建了,幸運的是 nerdctl 就提供了 nerdctl build 這樣的鏡像構建命令,

🐳nerdctl build:從 Dockerfile 構建鏡像

比如現在我們定制一個 nginx 鏡像,新建一個如下所示的 Dockerfile 檔案:

[root@containerd ~]#mkdir -p /root/nerctl_demo
[root@containerd ~]#cd /root/nerctl_demo/
[root@containerd nerctl_demo]#cat > Dockerfile <<EOF
> FROM nginx:alpine
> RUN echo 'Hello Nerdctl From Containerd' > /usr/share/nginx/html/index.html
> EOF
[root@containerd nerctl_demo]#cat Dockerfile
FROM nginx:alpine
RUN echo 'Hello Nerdctl From Containerd' > /usr/share/nginx/html/index.html

然后在檔案所在目錄執行鏡像構建命令:

[root@containerd nerctl_demo]#nerdctl build -t nginx:nerctl -f Dockefile .
FATA[0000] `buildctl` needs to be installed and `buildkitd` needs to be running, see https://github.com/moby/buildkit: exec: "buildctl": executable file not found in $PATH
[root@containerd nerctl_demo]#

注意:也可以加上這個–no-cache選項

#--no-cache選項
--no-cache                Do not use cache when building the image (default: false)

image-20211025164720997

可以看到有一個錯誤提示,需要我們安裝 buildctl 并運行 buildkitd,這是因為 nerdctl build 需要依賴 buildkit 工具,

buildkit 專案也是 Docker 公司開源的一個構建工具包,支持 OCI 標準的鏡像構建,它主要包含以下部分:

  • 服務端 buildkitd:當前支持 runc 和 containerd 作為 worker,默認是 runc,我們這里使用 containerd
  • 客戶端 buildctl:負責決議 Dockerfile,并向服務端 buildkitd 發出構建請求

buildkit 是典型的 C/S 架構,客戶端和服務端是可以不在一臺服務器上,而 nerdctl 在構建鏡像的時候也作為 buildkitd 的客戶端,所以需要我們安裝并運行 buildkitd

https://github.com/moby/buildkit

image-20211025160621166

所以接下來我們先來安裝 buildkit

?  ~ wget https://github.com/moby/buildkit/releases/download/v0.9.1/buildkit-v0.9.1.linux-amd64.tar.gz
# 如果有限制,也可以替換成下面的 URL 加速下載
# wget https://download.fastgit.org/moby/buildkit/releases/download/v0.9.1/buildkit-v0.9.1.linux-amd64.tar.gz
[root@containerd ~]#ll -h buildkit-v0.9.1.linux-amd64.tar.gz
-rw-r--r-- 1 root root 46M Oct  5 03:51 buildkit-v0.9.1.linux-amd64.tar.gz
[root@containerd ~]#tar tf buildkit-v0.9.1.linux-amd64.tar.gz
bin/
bin/buildctl
bin/buildkit-qemu-aarch64
bin/buildkit-qemu-arm
bin/buildkit-qemu-i386
bin/buildkit-qemu-mips64
bin/buildkit-qemu-mips64el
bin/buildkit-qemu-ppc64le
bin/buildkit-qemu-riscv64
bin/buildkit-qemu-s390x
bin/buildkit-runc
bin/buildkitd
[root@containerd ~]#

?  ~ tar -zxvf buildkit-v0.9.1.linux-amd64.tar.gz -C /usr/local/containerd/
bin/
bin/buildctl
bin/buildkit-qemu-aarch64
bin/buildkit-qemu-arm
bin/buildkit-qemu-i386
bin/buildkit-qemu-mips64
bin/buildkit-qemu-mips64el
bin/buildkit-qemu-ppc64le
bin/buildkit-qemu-riscv64
bin/buildkit-qemu-s390x
bin/buildkit-runc
bin/buildkitd
?  ~ ln -s /usr/local/containerd/bin/buildkitd /usr/local/bin/buildkitd
?  ~ ln -s /usr/local/containerd/bin/buildctl /usr/local/bin/buildctl

這里我們使用 Systemd 來管理 buildkitd,創建如下所示的 systemd unit 檔案:

cat > /etc/systemd/system/buildkit.service <<EOF
[Unit]
Description=BuildKit
Documentation=https://github.com/moby/buildkit

[Service]
ExecStart=/usr/local/bin/buildkitd --oci-worker=false --containerd-worker=true

[Install]
WantedBy=multi-user.target
EOF

然后啟動 buildkitd

[root@containerd ~]#systemctl deamon-reload
Unknown operation 'deamon-reload'.
[root@containerd ~]#systemctl daemon-reload
[root@containerd ~]#systemctl enable buildkit --now
Created symlink from /etc/systemd/system/multi-user.target.wants/buildkit.service to /etc/systemd/system/buildkit.service.
[root@containerd ~]#systemctl status buildkit
● buildkit.service - BuildKit
   Loaded: loaded (/etc/systemd/system/buildkit.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2021-10-25 16:11:47 CST; 13s ago
     Docs: https://github.com/moby/buildkit
 Main PID: 26680 (buildkitd)
    Tasks: 7
   Memory: 13.5M
   CGroup: /system.slice/buildkit.service
           └─26680 /usr/local/bin/buildkitd --oci-worker=false --containerd-worker=true

Oct 25 16:11:47 containerd systemd[1]: Started BuildKit.
Oct 25 16:11:47 containerd buildkitd[26680]: time="2021-10-25T16:11:47+08:00" level=warning msg="using host network as the default"
Oct 25 16:11:47 containerd buildkitd[26680]: time="2021-10-25T16:11:47+08:00" level=info msg="found worker \"72ur53vv5olwy9wv0oc46...
Oct 25 16:11:47 containerd buildkitd[26680]: time="2021-10-25T16:11:47+08:00" level=info msg="found 1 workers, default=\"72u...cc6\""
Oct 25 16:11:47 containerd buildkitd[26680]: time="2021-10-25T16:11:47+08:00" level=warning msg="currently, only the default...used."
Oct 25 16:11:47 containerd buildkitd[26680]: time="2021-10-25T16:11:47+08:00" level=info msg="running server on /run/buildki....sock"
Hint: Some lines were ellipsized, use -l to show in full.
[root@containerd ~]#

#可以看下日志
[root@containerd ~]#journalctl -u buildkit
-- Logs begin at Sat 2021-10-23 13:52:41 CST, end at Mon 2021-10-25 16:11:47 CST. --
Oct 25 16:11:47 containerd systemd[1]: Started BuildKit.
Oct 25 16:11:47 containerd buildkitd[26680]: time="2021-10-25T16:11:47+08:00" level=warning msg="using host network as the default"
Oct 25 16:11:47 containerd buildkitd[26680]: time="2021-10-25T16:11:47+08:00" level=info msg="found worker \"72ur53vv5olwy9wv0oc46bcc
Oct 25 16:11:47 containerd buildkitd[26680]: time="2021-10-25T16:11:47+08:00" level=info msg="found 1 workers, default=\"72ur53vv5olw
Oct 25 16:11:47 containerd buildkitd[26680]: time="2021-10-25T16:11:47+08:00" level=warning msg="currently, only the default worker c
Oct 25 16:11:47 containerd buildkitd[26680]: time="2021-10-25T16:11:47+08:00" level=info msg="running server on /run/buildkit/buildki
lines 1-7/7 (END)

現在我們再來重新構建鏡像:

[root@containerd ~]#cd nerctl_demo/
[root@containerd nerctl_demo]#ls
Dockerfile
[root@containerd nerctl_demo]#nerdctl build  -t nginx:nerctl -f Dockerfile .
[+] Building 7.2s (6/6) FINISHED
 => [internal] load build definition from Dockerfile                                                                            0.0s
 => => transferring dockerfile: 131B                                                                                            0.0s
 => [internal] load .dockerignore                                                                                               0.0s
 => => transferring context: 2B                                                                                                 0.0s
 => [internal] load metadata for docker.io/library/nginx:alpine                                                                 4.1s
 => [1/2] FROM docker.io/library/nginx:alpine@sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3           1.1s
 => => resolve docker.io/library/nginx:alpine@sha256:686aac2769fd6e7bab67663fd38750c135b72d993d0bb0a942ab02ef647fc9c3           0.0s
 => => extracting sha256:a0d0a0d46f8b52473982a3c466318f479767577551a53ffc9074c9fa7035982e                                       0.2s
 => => extracting sha256:4dd4efe90939ab5711aaf5fcd9fd8feb34307bab48ba93030e8b845f8312ed8e                                       0.8s
 => => extracting sha256:c1368e94e1ec563b31c3fb1fea02c9fbdc4c79a95e9ad0cac6df29c228ee2df3                                       0.0s
 => => extracting sha256:3e72c40d0ff43c52c5cc37713b75053e8cb5baea8e137a784d480123814982a2                                       0.0s
 => => extracting sha256:969825a5ca61c8320c63ff9ce0e8b24b83442503d79c5940ba4e2f0bd9e34df8                                       0.0s
 => => extracting sha256:61074acc7dd227cfbeaf719f9b5cdfb64711bc6b60b3865c7b886b7099c15d15                                       0.0s
 => [2/2] RUN echo 'Hello Nerdctl From Containerd' > /usr/share/nginx/html/index.html                                           0.5s
 => exporting to oci image format                                                                                               1.3s
 => => exporting layers                                                                                                         0.3s
 => => exporting manifest sha256:c5ab5ef3d410c1e7e8140eaf48f92c7b2a70d6f8d75a4bd26636db0e886101aa                               0.0s
 => => exporting config sha256:faa17ba50c10a48d128f1369bca7640083c48249239d9dd95ea30f88a4e387b5                                 0.0s
 => => sending tarball                                                                                                          0.9s
unpacking docker.io/library/nginx:nerctl (sha256:c5ab5ef3d410c1e7e8140eaf48f92c7b2a70d6f8d75a4bd26636db0e886101aa)...done
[root@containerd nerctl_demo]#nerdctl images
REPOSITORY    TAG       IMAGE ID        CREATED          SIZE
nginx         alpine    686aac2769fd    47 hours ago     24.9 MiB
nginx         nerctl    c5ab5ef3d410    9 seconds ago    24.9 MiB
[root@containerd nerctl_demo]#

image-20211025162157955

構建完成后查看鏡像是否構建成功:

[root@containerd nerctl_demo]#nerdctl images
REPOSITORY    TAG       IMAGE ID        CREATED          SIZE
nginx         alpine    686aac2769fd    47 hours ago     24.9 MiB
nginx         nerctl    c5ab5ef3d410    9 seconds ago    24.9 MiB
[root@containerd nerctl_demo]#

我們可以看到已經有我們構建的 nginx:nerdctl 鏡像了,接下來使用上面我們構建的鏡像來啟動一個容器進行測驗:

[root@containerd ~]#nerdctl ps -a
CONTAINER ID    IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES
[root@containerd ~]#nerdctl images
REPOSITORY    TAG       IMAGE ID        CREATED          SIZE
nginx         alpine    686aac2769fd    47 hours ago     24.9 MiB
nginx         nerctl    c5ab5ef3d410    4 minutes ago    24.9 MiB
[root@containerd ~]#nerdctl run -d -p 80:80 --name=nginx88  nginx:nerctl
1a5ae8262e78b3c0bf9e9da56789b9b6529e11ab7b53934841ada4e712210001
[root@containerd ~]#nerdctl ps -a
CONTAINER ID    IMAGE                             COMMAND                   CREATED          STATUS    PORTS                 NAMES
1a5ae8262e78    docker.io/library/nginx:nerctl    "/docker-entrypoint.…"    6 seconds ago    Up        0.0.0.0:80->80/tcp    nginx88
[root@containerd ~]#curl localhost
Hello Nerdctl From Containerd
[root@containerd ~]#

image-20211025162642012

這樣我們就使用 nerdctl + buildkitd 輕松完成了容器鏡像的構建,

完美,

當然如果你還想在單機環境下使用 Docker Compose,在 containerd 模式下,我們也可以使用 nerdctl 來兼容該功能,同樣我們可以使用 nerdctl composenerdctl compose upnerdctl compose logsnerdctl compose buildnerdctl compose down 等命令來管理 Compose 服務,這樣使用 containerd、nerdctl 結合 buildkit 等工具就完全可以替代 docker 在鏡像構建、鏡像容器方面的管理功能了,

[root@containerd ~]#nerdctl volume ls
VOLUME NAME    DIRECTORY
[root@containerd ~]#nerdctl network ls
NETWORK ID    NAME              FILE
0             bridge
              containerd-net    /etc/cni/net.d/10-containerd-net.conflist
              host
              none
[root@containerd ~]#nerdctl namespace ls
NAME        CONTAINERS    IMAGES    VOLUMES
buildkit    0             0         0
default     1             2         0
test        0             1         0
[root@containerd ~]#

需要注意的問題

?(待解決)nerdctl run命令創建出的容器在宿主機上看不到埠號,奇怪

  • 很奇怪,這個現象:

創建的容器映射到宿主機上的埠,在宿主機上沒有查看的到,–>是個遺留問題,老師說正常情況是可以看到的才對,可能是底層走的是iptables,老師也沒排查出來,當做遺留問題,

測驗程序如下:

查看環境:

[root@containerd ~]#ctr i ls -q
docker.io/library/nginx:alpine
[root@containerd ~]#ctr t ls
TASK    PID    STATUS
[root@containerd ~]#netstat -ntlp #沒有80埠被占用
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:42797         0.0.0.0:*               LISTEN      8116/containerd
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      6587/sshd
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      6858/master
tcp6       0      0 :::22                   :::*                    LISTEN      6587/sshd
tcp6       0      0 ::1:25                  :::*                    LISTEN      6858/master
[root@containerd ~]#

創建容器:

[root@containerd ~]#nerdctl run -d -p 80:80 --name=nginx_bak docker.io/library/nginx:alpine
daf6ed8901335002c2edde96a3639da4a201f44a1ed74cb2b6a29221bf2603cb
[root@containerd ~]#

驗證:

發現容器是創建成功了,但是宿主機上是沒有出現這個80埠,很奇怪:

[root@containerd ~]#ctr t ls
TASK                                                                PID      STATUS
daf6ed8901335002c2edde96a3639da4a201f44a1ed74cb2b6a29221bf2603cb    28327    RUNNING
[root@containerd ~]#ctr c ls
CONTAINER                                                           IMAGE                             RUNTIME
daf6ed8901335002c2edde96a3639da4a201f44a1ed74cb2b6a29221bf2603cb    docker.io/library/nginx:alpine    io.containerd.runc.v2
[root@containerd ~]#ps -ef|grep nginx
root      28327  28296  0 07:17 ?        00:00:00 nginx: master process nginx -g daemon off;
101       28441  28327  0 07:17 ?        00:00:00 nginx: worker process
101       28442  28327  0 07:17 ?        00:00:00 nginx: worker process
root      28503  28223  0 07:41 pts/0    00:00:00 grep --color=auto nginx
[root@containerd ~]#
[root@containerd ~]#curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@containerd ~]#


[root@containerd ~]#netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:42797         0.0.0.0:*               LISTEN      8116/containerd
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      6587/sshd
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      6858/master
tcp6       0      0 :::22                   :::*                    LISTEN      6587/sshd
tcp6       0      0 ::1:25                  :::*                    LISTEN      6858/master
[root@containerd ~]#ctr c info daf6ed8901335002c2edde96a3639da4a201f44a1ed74cb2b6a29221bf2603cb|less #但是通過ctr c info id也能看到ports的資訊啊,,,

image-20211025072100076

?(待解決)還有個奇怪的問題就是:容器名被占用問題,,,

image-20211025072347002

這個我就想不通,原來創建的容器已經被洗掉了,怎么創建同名的容器還報錯呢,,,

??(已解決)nerdctl為啥沒有自動補全呢?

已解決!

和這個kubectl的一樣,按這個方法配置下就可以自動補全命令了,666.

image-20211025152941909

[root@containerd ~]#yum install -y epel-release bash-completion
[root@containerd ~]#source /usr/share/bash-completion/bash_completion
[root@containerd ~]#source <(nerdctl completion bash)
[root@containerd ~]#echo "source <(nerdctl completion bash)" >> ~/.bashrc
[root@containerd ~]#source ~/.bashrc
[root@containerd ~]#nerdctl r
rm   rmi  run
[root@containerd ~]#nerdctl r

??注意:不推薦使用commit去構建物件,而是要用build去構建物件

不推薦使用commit去構建物件,而是要用build去構建物件,—>不知道為啥,,,,

build       Build an image from a Dockerfile. Needs buildkitd to be running.
commit      [flags] CONTAINER REPOSITORY[:TAG]

??注意:用build構建鏡像時,下面這個.問題,

docker的架構是cs架構:all請求,包括構建鏡像

image-20211025103107892

image-20211025103210243

很多同學認為這里的點代表dockerfile的地址,其實這里的.和dockerfile的地址是有區別的:

dockerfile的地址你可以任意去指定;

其實這個點表示:構建背景關系,就是你所要構建檔案背景關系是在哪些地方,就是你dockerfile里面的東西都是相對于你背景關系的,因為你構建背景關系all的事情都是上傳到dockerd后臺的,你不要考慮在本地,

因此,有個不好的情況就是,假如說你的dockerfile檔案在/目錄下:

image-20211025103639801

可想而知,它會把你/目錄下all檔案全部上傳到dockerd上面去,就會特別特別慢,會出問題的,

所以,這里的點構建背景關系并不是隨便指定的,

image-20211025164009520

??注意:containerd網路,它對接的是cni

[root@containerd ~]#nerdctl network ls
NETWORK ID    NAME              FILE
0             bridge
              containerd-net    /etc/cni/net.d/10-containerd-net.conflist
              host
              none
[root@containerd ~]#

/etc/cni/net.d/,這個其實是我們標準CNI的一個配置方式:

就是我們后面要講的flannel都是放在這個下面的,

但是這種情況下,我們直接用這個組態檔去創建我們的k8s集群,即使你是創建的一個flannel網路插件,但是啟動起來pod后,它還是不會使用這個flannel插件的,就是這個目錄下的all conflist cni插件,好像是按這個字母順序來加載的,所以會優先加載這個10-containerd-net.conflist的,也就是containerd本地的一個網路配置:

image-20211025113422073

[root@containerd net.d]#cat 10-containerd-net.conflist
{
  "cniVersion": "0.4.0",
  "name": "containerd-net",
  "plugins": [
    {
      "type": "bridge",
      "bridge": "cni0",
      "isGateway": true,
      "ipMasq": true,
      "promiscMode": true,
      "ipam": {
        "type": "host-local",
        "ranges": [
          [{
            "subnet": "10.88.0.0/16"
          }],
          [{
            "subnet": "2001:4860:4860::/64"
          }]
        ],
        "routes": [
          { "dst": "0.0.0.0/0" },
          { "dst": "::/0" }
        ]
      }
    },
    {
      "type": "portmap",
      "capabilities": {"portMappings": true}
    }
  ]
}
[root@containerd net.d]#

就是一個bridge模式,

如果你自己要去創建網路也是可以的啊,和docker一樣,其實都是對接的我們cni,你可以認為它是可以直接去對接的:

[root@containerd ~]#nerdctl network ls
NETWORK ID    NAME              FILE
0             bridge
              containerd-net    /etc/cni/net.d/10-containerd-net.conflist
              host
              none
[root@containerd ~]#

就是你可以把這個/etc/cni/net.d/10-containerd-net.conflist給洗掉掉,然后你自己在下面創建一個cni的配置,也是可以的,

所以,你后面在k8s里如果使用containerd來搭建集群的話,你需要把/etc/cni/net.d/10-containerd-net.conflist這個給移除掉,否則可能你創建出的pod它所使用的網段都是/etc/cni/net.d/10-containerd-net.conflist里面的"subnet": “2001:4860:4860::/64”,沒有使用你的flannel插件配置或者你的其他網路插件,

??注意:nerdctl在構建鏡像時可以配置.dockerignore檔案的,

也就是說在構建鏡像時,可以配置下要忽略的檔案,否則這個檔案也一起會被提交到buildkitd后臺的,

image-20211025164257324

image-20211025164440883

關于我

我的博客主旨:我希望每一個人拿著我的博客都可以做出實驗現象,先把實驗做出來,然后再結合理論知識更深層次去理解技術點,這樣學習起來才有樂趣和動力,并且,我的博客內容步驟是很完整的,也分享原始碼和實驗用到的軟體,希望能和大家一起共同進步!

各位小伙伴在實際操作程序中如有什么疑問,可隨時聯系本人免費幫您解決問題:

  1. 個人微信二維碼:x2675263825 (舍得), qq:2675263825,

    image-20211002091450217

  2. 個人博客地址:www.onlyonexl.cn

    image-20211002092057988

  3. 個人微信公眾號:云原生架構師實戰

    image-20211002141739664

  4. 個人csdn

    https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

    image-20211002092344616

總結

? 好了,關于實戰Containerd高級命令列工具nerdctl安裝及使用實驗就到這里了,感謝大家閱讀,最后貼上我的美圓photo一張,祝大家生活快樂,每天都過的有意義哦,我們下期見!

image-20211025115640691

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/338125.html

標籤:其他

上一篇:無法實作for和while回圈以及如何添加要在選項卡面板中顯示的多個輸出

下一篇:如何從API回應中提取陣列

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more