Docker入門之安裝Docker


目錄

目錄 1

1. 前言 1

2. 創建網橋 2

3. 安裝Docker 2

3.1. 二進制安裝 3

3.1.1. 下載安裝 3

3.1.2. 配置服務 3

3.1.3. 啟動服務 4

3.2. rpm安裝 5

3.3. yum安裝 5

3.3.1. 添加Docker倉庫 5

3.3.2. 安裝docker-ce 6

3.3.3. 啟動服務 8

4. Docker基本操作 8

4.1. 啟動Docker服務 8

4.2. 查看有哪些images 8

4.3. 從倉庫拉取images 9

4.4. 運行image 10

4.5. 查看指定的image 10

4.6. 修改images存放目錄 11

4.7. 查看運行中的容器 11

4.8. 優雅停止容器 12

4.9. 強制停止容器 12

附1:rpm安裝 12

附2:yum安裝 12

附3:systemctl和systemd 14

附4:命令brctl 15

附5:命令ip 15

附6:內核模塊 16

附7:常見問題 18

前言

本文操作基於CentOS7,其它Linux發行版本可能存在差異,分基於yum的在線安裝和基於二進制包的離線安裝(實際還有基於rpm包的離線安裝),離線安裝可以更多地了解Docker及相關體系。

Docker要求Linux內核版本不低於3.10,並且必須為64位系統,執行命令“docker
version”可查看Docker版本。

CentOS7防火牆默認采用的是firewalld管理netfilter子系統,底層調用的仍然是iptables命令,firewalld實際是iptables的一個封裝。不同的防火牆相互間存在沖突,使用某其中一個時應禁用其他的。

創建網橋

啟動Docker之前(即執行命令“sytemctl start
docker.service”前),需要先創建和啟用好網橋。執行下例命令創建和設置網橋:

# ip link add name docker0 type bridge # 創建網橋 # ip addr add dev docker0 172.17.0.1/16 # 設置網橋的IP和網關 # ip link set docker0 up # 啟用網橋 # ip a # 查看創建好的網橋 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000 link/ether 60:eb:69:fe:2e:20 brd ff:ff:ff:ff:ff:ff 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000 link/ether 60:eb:69:fe:2e:21 brd ff:ff:ff:ff:ff:ff inet 10.22.25.101/26 brd 10.223.25.127 scope global eth1 valid_lft forever preferred_lft forever 4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN link/ether 6e:3c:cb:3e:a7:44 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 scope global docker0 valid_lft forever preferred_lft forever

網橋狀態為up,則表示沒有起來。如果沒有網橋或網橋沒有起來,執行“systemctl
start docker.service”啟動Docker時將可能遇到錯誤“list bridge addresses
failed
”而啟動失敗。

安裝Docker

在能訪問網絡的環境或者有本地Docker倉庫的環境,建議使用yum安裝,簡單省事。

在不能訪問網絡環境,可手工安裝Docker。進入https://download.docker.com/,下載對應的安裝包,這里又分兩種:一是下載通用的二進制安裝包,二是下載RPM安裝包。相對yum安裝,手工安裝(離線安裝)可以了解更多細節,有助於深入了解Docker。

二進制安裝

這個方法比較復雜,容易遇到各種問題。

下載安裝

通用的二進制安裝包下載路徑:https://download.docker.com/linux/static/stable/x86_64/,截至2019/12/17可下載的最新版本為docker-19.03.5.tgz,就以它為安裝對象。下載好后,將docker-19.03.5.tgz上傳到目標Linux的任一目錄,然后進入該目錄解壓docker-19.03.5.tgz,解壓后的內容如下:

# ls /usr/bin/docker containerd containerd-shim ctr docker dockerd docker-init docker-proxy runc

解壓生成的目錄Docker下全是64位可執行程序文件,其中dockerd是運行在母機上的服務,dockerd負責加載images拉起容器container。

# ls -l /usr/bin/docker 總用量 204720 -rwxr-xr-x 1 root root 34625816 2019-11-13 15:30 containerd -rwxr-xr-x 1 root root 6116160 2019-11-13 15:30 containerd-shim -rwxr-xr-x 1 root root 18850136 2019-11-13 15:30 ctr -rwxr-xr-x 1 root root 65641786 2019-11-13 15:30 docker -rwxr-xr-x 1 root root 72090824 2019-11-13 15:30 dockerd -rwxr-xr-x 1 root root 764144 2019-11-13 15:30 docker-init -rwxr-xr-x 1 root root 2877369 2019-11-13 15:30 docker-proxy -rwxr-xr-x 1 root root 8649792 2019-11-13 15:30 runc

將目錄“/usr/bin/docker”加入到環境變量PATH中,如果不這么做,則可將目錄/usr/bin/docker下的所有文件復制到目錄“/usr/bin”。

配置服務

新建和編輯文件docker.service,文件docker.service所在目錄可有多種選擇,實際為systemd查找目錄,執行命令“man
5 systemd.unit
”或“man 5 systemd.service”可看到所支持的目錄包含如下一些:

目錄 說明
/etc/systemd/system Local configuration
/run/systemd/system Runtime units
/usr/lib/systemd/system Units of installed packages yum方式安裝時,docker.service可能在此目錄

以“/etc/systemd/system/docker.service”為例:

# cat /etc/systemd/system/docker.service [Unit] Description=Docker Application Container Engine Documentation=http://docs.docker.com After=network.target rhel-push-plugin.socket Wants=docker-storage-setup.service [Service] Type=notify NotifyAccess=all EnvironmentFile=-/etc/sysconfig/docker EnvironmentFile=-/etc/sysconfig/docker-storage EnvironmentFile=-/etc/sysconfig/docker-network Environment=GOTRACEBACK=crash ExecStart=/usr/bin/dockerd daemon \ --graph /data/docker \ --exec-opt native.cgroupdriver=systemd \ $OPTIONS \ $DOCKER_STORAGE_OPTIONS \ $DOCKER_NETWORK_OPTIONS \ $ADD_REGISTRY \ $BLOCK_REGISTRY \ $INSECURE_REGISTRY LimitNOFILE=1048576 LimitNPROC=1048576 LimitCORE=infinity TimeoutStartSec=0 MountFlags=slave Restart=on-abnormal [Install] WantedBy=multi-user.target

其中“--graph”用於指定images存放目錄。

啟動服務

執行命令“systemctl start docker.service”啟動Docker:

# systemctl start docker.service # ps aux|grep docker | grep -v grep root 16052 0.3 0.1 600076 37332 ? Ssl 16:46 0:00 /usr/bin/docker/dockerd --data-root /data/docker --exec-opt native.cgroupdriver=systemd root 16060 0.1 0.0 571644 22196 ? Ssl 16:46 0:00 containerd --config /var/run/docker/containerd/containerd.toml --log-level info

rpm安裝

https://download.docker.com/linux/centos/7/x86_64/stable/Packages/下載RPM安裝包,以下載docker-ce-19.03.5-3.el7.x86_64.rpm、docker-ce-cli-19.03.5-3.el7.x86_64.rpm、containerd.io-1.2.6-3.3.el7.x86_64.rpm、docker-ce-selinux-17.03.3.ce-1.el7.noarch.rpm為例,其中docker-ce-19.03.5-3.el7.x86_64.rpm依賴其它幾個RPM包,而containerd.io-1.2.6-3.3.el7.x86_64.rpm又依賴docker-ce-selinux

基於RPM包安裝涉及很多依賴,安裝可能復雜(視實際的依賴程度),所以盡量避免這種安裝方式。本文嘗試時,因為太多的依賴需要安裝或更新,導致未能完成。

yum安裝

yum會將Docker安裝到/usr/bin目錄,可執行“ls
/usr/bin/dock*”查看有哪些文件,不同版本會有差異。

實際上可以用yum安裝RPM包,但和直接使用RPM命令一樣,有復雜的依賴問題,所以除非不得已,最好不要采用yum+RPM包方式安裝。這節介紹可訪問網絡(能訪問Docker倉庫)時的yum安裝。

需要安裝的內容包括:

包名 說明
docker-ce 社區版(Community)容器引擎(Docker Engine),依賴containerd.io。包含了: /usr/bin/dockerd /usr/bin/docker-init /usr/bin/docker-proxy
docker-ce-cli docker-ce的命令行客戶端工具,包含了命令行客戶端工具/usr/bin/docker
containerd.io 隔離了Docker和OS(比如Linux容器LXC),有獨立的官網:https://containerd.io/
docker 對社區版而言,就是docker-ce,有些非官方倉庫需要使用這個名字安裝,使用docker-ce報“No package docker-ce available”。

其中docker-ce為容器引擎,安裝步驟:

添加Docker倉庫

這一步不一定是必須的,比如內網已配置好本地倉庫而不需要訪問Docker官方倉庫,或者已添加好Docker官方倉庫。

如果yum-config-manager不可用,則需執行“yum install -y
yum-utils”先安裝好yum-config-manager。

執行下列命令添加Docker倉庫:

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

完成后,可以目錄/etc/yum.repos.d下看到文件docker-ce.repo。如果執行失敗,則文件docker-ce.repo為空文件。

安裝docker-ce

執行下列命令安裝:

# yum -y install docker-ce

如果報“No package docker-ce available”,可改成下列試試:

# yum -y install docker

安裝成功后,會產生新文件:

# file /usr/lib/systemd/system/docker.service /usr/lib/systemd/system/docker.service: cannot open (No such file or directory) # ls /usr/bin/dock* ls: cannot access /usr/bin/dock*: No such file or directory # yum -y install docker-ce # file /usr/lib/systemd/system/docker.service /usr/lib/systemd/system/docker.service: ASCII text # ls /usr/bin/dock* /usr/bin/docker /usr/bin/docker-fetch /usr/bin/dockertarsum

其中docker.service供systemd使用,當執行“systemctl start
docker.service”時依賴文件docker.service定義的信息。文件docker.service不一定要位於目錄/usr/lib/systemd/system/,systemd支持搜索多個目錄查找docker.service,比如二進制安裝時將docker.service放在目錄/etc/systemd/system。

默認的文件docker.service內容如下:

# cat /usr/lib/systemd/system/docker.service [Unit] Description=Docker Application Container Engine Documentation=http://docs.docker.com After=network.target [Service] Type=notify EnvironmentFile=-/etc/sysconfig/docker EnvironmentFile=-/etc/sysconfig/docker-storage EnvironmentFile=-/etc/sysconfig/docker-network ExecStart=/usr/bin/docker -d $OPTIONS \ $DOCKER_STORAGE_OPTIONS \ $DOCKER_NETWORK_OPTIONS \ $ADD_REGISTRY \ $BLOCK_REGISTRY \ $INSECURE_REGISTRY LimitNOFILE=1048576 LimitNPROC=1048576 LimitCORE=infinity MountFlags=slave TimeoutSec=0 [Install] WantedBy=multi-user.target

其中參數“-d”表示以后台守護進程方式啟動,配置項“WantedBy”用於指定隨系統啟動時docker.service發布的子目錄為“multi-user.target”。注意“multi-user.target”的名不能隨便取,這是systemd約定的名之一,對應系統啟動級別3,可通過命令“systemctl
set-default”修改默認級別,multi-user.target的完整目錄路徑為/etc/systemd/system/multi-user.target。

官方最新的docker.service如下:

# cat /usr/lib/systemd/system/docker.service [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com BindsTo=containerd.service After=network-online.target firewalld.service containerd.service Wants=network-online.target Requires=docker.socket [Service] Type=notify # the default is not to use systemd for cgroups because the delegate issues still # exists and systemd currently does not support the cgroup feature set required # for containers run by docker ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always # Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229. # Both the old, and new location are accepted by systemd 229 and up, so using the old location # to make them work for either version of systemd. StartLimitBurst=3 # Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230. # Both the old, and new name are accepted by systemd 230 and up, so using the old name to make # this option work for either version of systemd. StartLimitInterval=60s # Having non-zero Limit*s causes performance problems due to accounting overhead # in the kernel. We recommend using cgroups to do container-local accounting. LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity # Comment TasksMax if your systemd version does not support it. # Only systemd 226 and above support this option. TasksMax=infinity # set delegate yes so that systemd does not reset the cgroups of docker containers Delegate=yes # kill only the docker process, not all processes in the cgroup KillMode=process [Install] WantedBy=multi-user.target

啟動服務

執行命令“systemctl start docker.service”啟動Docker:

# systemctl start docker.service # ps aux|grep docker | grep -v grep /usr/bin/docker -d --selinux-enabled -b=none

Docker基本操作

啟動Docker服務

和其它服務一樣啟動即可,停止和重啟方法也相同。

# systemctl start docker.service

查看有哪些images

# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/hello-world latest fce289e99eb9 11 months ago 1.84 kB

如果Docker服務沒有起來,執行“docker images”將報如下錯誤:

# docker images Cannot connect to the Docker daemon. Is the docker daemon running on this host?

從倉庫拉取images

默認拉取到的是latest鏡射(image)。

# docker pull hello-world Using default tag: latest Trying to pull repository docker.io/library/hello-world ... latest: Pulling from docker.io/library/hello-world 1b930d010525: Pull complete

如果執行命令“docker
images”看不到拉取的image,則可重拉取后再看看。如果從非Docker官方(docker.io)拉取image,則需要指定倉庫地址:

# docker pull myrep.io/public/hello-world

如不確定hello-world所在路徑,則可先執行“docker search myrep.io/hello”查找:

# docker search myrep.io/hello-world

如果沒有latest版鏡像,則可指定版本:

# docker pull myrep.io/public/hello-world:v1

注意,這里並不是“docker pull
http://myrep.io/public/hello-world”,沒有“http://”或“https://”前綴,否則報錯“is
not a valid repository/tag: invalid reference format”。

拉取下來的images存放在哪?請參見《指定Docker的images存放目錄》一節的內容。官方的“hello-world”鏡像長這樣子:

# cat /data/docker/image/aufs/imagedb/content/sha256/fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e {"architecture":"amd64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/hello"],"ArgsEscaped":true,"Image":"sha256:a6d1aaad8ca65655449a26146699fe9d61240071f6992975be7e720f1cd42440","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"8e2caa5a514bb6d8b4f2a2553e9067498d261a0fd83a96aeaaf303943dff6ff9","container_config":{"Hostname":"8e2caa5a514b","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/hello\"]"],"ArgsEscaped":true,"Image":"sha256:a6d1aaad8ca65655449a26146699fe9d61240071f6992975be7e720f1cd42440","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2019-01-01T01:29:27.650294696Z","docker_version":"18.06.1-ce","history":[{"created":"2019-01-01T01:29:27.416803627Z","created_by":"/bin/sh -c #(nop) COPY file:f77490f70ce51da25bd21bfc30cb5e1a24b2b65eb37d4af0c327ddc24f0986a6 in / "},{"created":"2019-01-01T01:29:27.650294696Z","created_by":"/bin/sh -c #(nop) CMD [\"/hello\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:af0b15c8625bb1938f1d7b17081031f649fd14e6b233688eea3c5483994a66a3"]}}

運行image

以“hello-world”為例:

# docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/

查看指定的image

# docker inspect hello-world [ { "Id": "sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e", "RepoTags": [ "docker.io/hello-world:latest" ], 。。。 。。。

修改images存放目錄

對於CentOS7,修改文件/usr/lib/systemd/system/docker.service,為docker-current指定命令行參數--graph,比如將目錄設置為/data/docker。

注意有些版本的叫/usr/bin/docker-current,有些叫/usr/bin/docker,有些叫/usr/bin/dockerd,而且參數會有差異。啟動遇到錯誤時,可只帶參數“--help”查看幫助,比如執行“dockerd
--help”。

ExecStart=/usr/bin/docker-current daemon \ --graph /data/docker \ --exec-opt native.cgroupdriver=systemd \ $OPTIONS \ $DOCKER_STORAGE_OPTIONS \ $DOCKER_NETWORK_OPTIONS \ $ADD_REGISTRY \ $BLOCK_REGISTRY \ $INSECURE_REGISTRY

“--graph
/data/docker”也可寫成“--graph=/data/docker”,效果是一樣的。另外,還可通過docker-current的命令行參數“--registry-mirror=”指定images倉庫。

在文件docker.service發生變化后,需要執行一次“systemctl
daemon-reload
”通知systemd重新加載,否則使用的仍然是老的配置。

執行“systemctl restart
docker.service”重啟啟動,然后執行ps命令可看到相關的變化:

# ps aux|grep docker root 21757 0.0 0.0 358584 21060 ? Ssl 09:45 0:00 /usr/bin/docker-current daemon --graph /data/docker --exec-opt native.cgroupdriver=systemd --selinux-enabled --log-driver=journald -b=none --iptables=false

以鏡像“hello-world”為例,它的路徑為:

/data/docker/image/aufs/imagedb/content/sha256/fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e

其中“sha256”后面為鏡像“hello-world”內容的sha256值:

# cat /data/docker/image/aufs/imagedb/content/sha256/fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e | openssl dgst -sha256 -hex (stdin)= fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e

查看運行中的容器

# docker ps

優雅停止容器

先向容器進程發送信號SIGTERM,10秒后再發送SIGKILL。

# docker stop

強制停止容器

直接向容器進程發信號SIGKILL。

# docker kill

附1:rpm安裝

RPM包實際也是一個壓縮包,為“RedHat Package
Manager”的縮寫,在Windows上可用7-zip等軟件直接打開見其盧山真面目。以下是RPM命令的常見應用:

命令 作用 說明
rpm -ivh packagename.rpm 安裝 -i為install之意,即安裝,等同--install; -v為verbose之意,即顯示詳細信息,等同--verbose; -h為hash之意,即顯示進度信息,等同--hash。
rpm -ivh packagename.rpm --nodeps 強制安裝,並忽略依賴
rpm -ivh packagename.rpm --force 強制安裝,不忽略依賴
rpm -e packagename 卸載
rpm -qi packagename 查看信息
rpm -pq packagename.rpm 查詢安裝后的名字
rpm -ql packagename 查詢安裝后生成的文件
rpm -qlp packagename.rpm 查詢安裝后生成的文件

RPM沒有解決包依賴問題,所以使用它安裝時,可能會遇到很多依賴包版本不匹配或者依賴的包不存在問題。就Docker而言,使用RPM包安裝,可能並不簡單,如果不能yum安裝,則更建議直接二進制安裝。

Docker
RPM包可在https://download.docker.com/linux/centos/7/x86_64/stable/Packages/上找到。

container-selinux等部分包可在http://mirror.centos.org/centos/7/extras/x86_64/Packages/上找到。

附2:yum安裝

Linux上的yum是一個Python腳本,為“Yellow dog Updater,
Modified”的縮寫,基於RPM的Shell前端軟件包管理器。

/etc/yum.conf為yum的配置文件,倉庫配置放在目錄/etc/yum.repos.d下。如果需添加本地倉庫,可在目錄/etc/yum.repos.d下新建一倉庫配置,然后清除下緩存,執行“yum
repolist”即可看到。

以下是yum命令的常見應用:

命令 作用 說明
yum list all 列舉出倉庫中的所有包
yum list installed 列舉已安裝的
yum list available 列舉可安裝的包
yum repolist all 列舉出所有倉庫,含禁用的
yum repolist 列舉出可用的倉庫 等同“yum repolist enabled”
yum repolist disabled 列舉出禁用的倉庫
yum clean all 清除所有緩存
yum search packagename 查找可安裝的包 示例: yum search docker
yum info packagename 查詢包的摘要信息 示例: yum info docker
yum deplist packagename 查看包依賴 示例: yum deplist docker
yum list all packagename 查看倉庫中指定名的包 救命: yum list all docker
yum -y install packagename 安裝 示例1(安裝單個): yum -y install docker 示例2(安裝多個): yum -y install \ docker-ce \ docker-ce-cli \ containerd.io \ docker
yum -y remove packagenameX 刪除安裝的包 注意packagenameX是命令yum list installed列出的包名(第1列),比如docker-ce-cli.x86_64。 示例1: yum -y remove docker.x86_64 示例2: yum -y remove \ docker-ce-cli.x86_64
yum-config-manager \ --add-repo=ADDREPO 添加和啟用一個新的倉庫,執行時會在目錄/etc/yum.repos.d下生成一個repo文件。 示例: yum-config-manager \ --add-repo=\ https://download.docker.com/linux/centos/docker-ce.repo 如果沒有yum-config-manager,則可用下列命令安裝: yum install -y yum-utils \ device-mapper-persistent-data \ lvm2 yum-config-manager是包yum-utils中的一員。

附3:systemctl和systemd

常見systemctl用法:

命令 作用 說明
systemctl start service 啟動服務 示例1: system start docker.service 或 system start docker
systemctl stop service 停止服務 示例1 system stop crond 或 system stop crond.service
systemctl restart service 重啟服務
systemctl enable service 設置服務隨系統自動啟動 以docker.service為例,“systemctl enable service”的作用實際等同於: ln -s \ '/etc/systemd/system/docker.service' \ '/etc/systemd/system/multi-user.target.wants/docker.service'
systemctl disable service 取消服務隨系統自動啟動 以docker.service為例,“systemctl disable service”的作用實際等同於: rm '/etc/systemd/system/multi-user.target.wants/docker.service'
systemctl status service 查看服務狀態
systemctl reload 重加載配置 當修改諸如docker.service文件時,需要執行一次reload
systemctl reboot 重啟系統
systemctl set-default 設置默認的啟動級別,其中multi-user.target對應級別3,graphical.target對應級別5 示例1: systemctl \ set-default \ multi-user.target 示例2: systemctl \ set-default \ graphical.target

systemctl類似於Windows平台的服務管理器,工作原理是通過與服務systemd交互完成各項工作,比如重啟crond進程。

systemd是Linux系統啟動后的第一個進程,取代了以前的init進程。systemd進程和init進程不會同時存在,低版本Linux為init,高版本Linux為systemd。

“systemctl status”和“systemctl -l
status”輸出的信息實際來源於系統日志文件“/var/log/message”。

當使用“systemctl start”啟動一個服務失敗,通過“systemctl -l
status”又找不到確切原因時,可嘗試直接執行service文件(比如docker.service)中ExecStart的定義的命令,這樣可能可查明失敗原因。

附4:命令brctl

可用brctl命令管理網橋,為包bridge-utils中的一員。

命令 作用 說明
brctl addbr <bridge> 創建網橋 示例: brctl addbr docker0
brctl delbr <bridge> 刪除網橋 示例: brctl delbr docker0
brctl show <bridge> 查詢網橋信息
brctl setfd <bridge> <time> 設置網橋轉發延遲 示例: brctl setfd docker0 10
brctl addif <bridge> <device> 網卡接入網橋 示例: brctl addif docker0 eth1
brctl delif <bridge> <device> 刪除接入網橋的網卡
brctl stp <bridge> <on> 啟用網橋 示例: brctl stp docker0 on
brctl stp <bridge> <off> 禁用網橋
brctl showmacs <bridge> 查看mac信息 示例: brctl showmacs docker0

附5:命令ip

Linux中網格管理命令,功能覆蓋ifconfig、netstat、route、arp等命令,是一個十分強大的大而全集成工具。為包iproute中的一員,而netstat和ifconfig為包net-tools包中的一員(執行“rpm
-ql net-tools”可查看)。

常見對比:

Ifconfig/netstat命令 ip命令
歸屬包 net-tools iproute
ifconfig ip link
ifconfig eth0 up ip link set eth0 up
查看所有接口,包括已禁用的 ifconfig -a ip addr show或ip a
ifconfig -s ip -s link
netstat -i ip -s link
netstat -r ip route

還可使用命令ip創建和設置網橋:

  1. 創建網橋
ip link add name docker0 type bridge

注:執行“ip link help”可查看“ip link”的使用幫助。

  1. 設置網橋的IP和網關
ip addr add dev docker0 172.17.0.1/16

注:“172.17.0.1/16”中的“172.17.0.1”為網橋的IP地址,16表示16個1,對應的網關地址為255.255.0.0(十填制數255對應的二進制值為11111111)。

  1. 啟用網橋
ip link set docker0 up
  1. 禁用網橋
ip link set docker0 down
  1. 刪除網橋
ip link delete docker0 type bridge

附6:內核模塊

Linux內核模塊放在目錄/lib/modules/`uname -r`/kernel下,模塊文件以“.ko”為后綴:

# file /lib/modules/`uname -r`/kernel/net/netfilter/nf_nat.ko /lib/modules/3.10.107-1-0046/kernel/net/netfilter/nf_nat.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=1a7527386082c922caeb208c7c9a1d530c079f1d, not stripped
  1. 查看模塊信息

使用命令modinfo查看模塊信息

# modinfo xt_limit.ko filename: /lib/modules/3.10.107-1-0046/kernel/net/netfilter/xt_limit.ko alias: ip6t_limit alias: ipt_limit description: Xtables: rate-limit match author: Herve Eychenne <rv@wallfire.org> license: GPL srcversion: B22C9E4BCCDBDFBFD5D4EFD depends: intree: Y vermagic: 3.10.107-1-0046 SMP mod_unload modversions signer: sig sig_key: 6E:69:6E:67:20:6B:65:79:2C:94:15:C6:82:EA:DB:06:CF:5A:37:57:72:EE:7A:58:2D:CA:23:38 sig_hashalgo: sha512
  1. 查看已加載模塊

使用命令lsmod查看已加載模塊列表:

# lsmod Module Size Used by nf_nat 26754 0 ip6t_rpfilter 12546 1 ip6t_REJECT 12939 2 nf_conntrack_ipv6 18738 4 nf_defrag_ipv6 34651 1 nf_conntrack_ipv6 # lsmod | grep nf_nat nf_nat 26754 0 nf_conntrack 96187 4 nf_nat,xt_conntrack,nf_conntrack_ipv4,nf_conntrack_ipv6
  1. 卸載模塊

使用命令rmmod卸載模塊:

# rmmod nf_nat_proto_udplite # rmmod nf_nat.ko
  1. 加載模塊

使用命令insmod加載模塊,要求指定模塊文件名的全路徑或相對路徑:

# insmod ./nf_nat_proto_udplite.ko # insmod netfilter/nf_nat.ko

也可使用modprobe加載模塊,這種方式不需要指定模塊路徑。modprobe依靠文件/lib/modules/`uname
-r`/modules.dep來查找模塊文件,因此當在目錄/lib/modules/`uname
-r`/kernel下有新增模塊文件時,需要先執行一次depmod命令,才能執行modprobe加載模塊,否則報錯:

# modprobe nf_nat modprobe: FATAL: Module nf_nat not found.

如果模塊格式不匹配,將報如下所示錯:

# modprobe nf_nat modprobe: ERROR: could not insert 'nf_nat': Exec format error # insmod ./nf_nat.ko insmod: ERROR: could not insert module ./nf_nat.ko: Invalid module format
  1. 更新模塊依賴關系

模塊依賴關系文件為/lib/modules/`uname
-r`/modules.dep,當有在目錄/lib/modules/`uname
-r`/kernel下新增模塊文件后,需要執行一次depmod來更新文件modules.dep,否則modprobe將找不到模塊文件。

附7:常見問題

  1. failed to create NAT chain DOCKER

執行“systemctl start docker.service”試圖啟動docker時報如下錯誤:

# systemctl -l status docker.service failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: Iptables not found docker.service: main process exited, code=exited, status=1/FAILURE Failed to start Docker Application Container Engine. Unit docker.service entered failed state.

這個錯誤是因為沒有啟動iptables,導致Docker無法做端口轉發,執行命令“systemctl
status firewalld”查看防火牆狀態:

# systemctl status firewalld firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled) Active: inactive (dead)

firewalld沒有起來,啟動它(disabled表示不隨系統自動啟動):

# systemctl start firewalld # systemctl status firewalld firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled) Active: active (running) since 三 2019-12-18 16:14:07 CST; 4s ago Main PID: 8066 (firewalld) CGroup: /system.slice/firewalld.service └─8066 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid 12月 18 16:14:07 X.site systemd[1]: Started firewalld - dynamic firewall daemon.

在CentOS7中雖然iptables仍然存在,但請使用firewalld來取代iptables服務。執行“systemctl
start
iptables”啟動iptables,將會自動停止firewalld,所以不要啟動iptables.service。

  1. Failed to start firewalld - dynamic firewall daemon

執行“systemctl status firewalld.service”時報如下錯誤:

# systemctl status firewalld.service firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled) Active: failed (Result: exit-code) since 三 2019-12-18 15:46:41 CST; 4s ago Process: 6381 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=exited, status=1/FAILURE) Main PID: 6381 (code=exited, status=1/FAILURE) 12月 18 15:46:41 X.site systemd[1]: firewalld.service: main process exited, code=exited, status=1/FAILURE 12月 18 15:46:41 X.site systemd[1]: Failed to start firewalld - dynamic firewall daemon. 12月 18 15:46:41 X.site systemd[1]: Unit firewalld.service entered failed state.

上述錯誤信息不是很明確,不足以分析出問題。/usr/sbin/firewalld實際上是一個Python腳本,由/usr/lib/systemd/system/firewalld.service中定義拉起firewalld:

ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS

可手工執行看看情況:

ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS

手工執行:

# /usr/sbin/firewalld --nofork --nopid Traceback (most recent call last): File "/usr/sbin/firewalld", line 34, in <module> from firewall import config ImportError: No module named firewall

錯誤信息顯示沒有名為firewall的Python模塊(修復這個后,仍然可能缺失其它模塊,需逐一排查,查看文件/usr/sbin/firewalld可了解到所依賴的其它模塊),簡單點可直接從其它機器復制一份過來。先找到firewall在其它機器上的位置:

# python Python 2.7.5 (default, Nov 20 2015, 02:00:19) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import firewall >>> print firewall._file_ /usr/lib/python2.7/site-packages/firewall/init.pyc >>>

注意,不同機器Python包的位置可能不同,可查看sys.path值來確認包存放在哪些目錄下。

另外,請注意/usr/sbin/firewalld中使用的Python是否正確(注意python的路徑):

# head -1 /usr/sbin/firewalld #!/usr/bin/python -Es
  1. can't initialize iptables table `nat'

執行命令“iptables -t nat -F”時報如下錯誤:

# iptables -t nat -F iptables v1.4.21: can't initialize iptables table `nat': Table does not exist (do you need to insmod?) Perhaps iptables or your kernel needs to be upgraded.

遇到這個錯誤時,可能需要重新配置和編譯內核。執行命令“modinfo
iptable_nat”檢查內核中是否有NAT模塊:

# modinfo iptable_nat modinfo: ERROR: Module iptable_nat not found.

如果沒有條件編譯內核,則可從其它地方將相關的模塊文件復制過來,復制過來后注意需執行一次depmod命令。相關路徑:“/lib/modules/`uname
-r`”。

如果模塊存在,則顯示如下(內核模塊文件名以“.ko”為后綴,ko為“Kernel
Object”的縮寫,depends顯示依賴的其它模塊):

# modinfo iptable_nat filename: /lib/modules/3.10.107-1-0050/kernel/net/ipv4/netfilter/iptable_nat.ko license: GPL srcversion: 22FC08135673BF996B25929 depends: nf_nat,ip_tables,nf_nat_ipv4,nf_conntrack intree: Y vermagic: 3.10.107-1-0050 SMP mod_unload modversions signer: sig sig_key: 6E:69:6E:67:20:6B:65:79:2C:94:15:C6:82:EA:DB:06:CF:5A:37:57:72:EE:7A:58:2D:CA:23:38 sig_hashalgo: sha512

其它模塊可同樣方法查看:

# modinfo nf_nat filename: /lib/modules/3.10.107-1-0050/kernel/net/netfilter/nf_nat.ko license: GPL srcversion: 5A7A5091ADF09B929C3EBC8 depends: nf_conntrack intree: Y vermagic: 3.10.107-1-0050 SMP mod_unload modversions signer: sig sig_key: 6E:69:6E:67:20:6B:65:79:2C:94:15:C6:82:EA:DB:06:CF:5A:37:57:72:EE:7A:58:2D:CA:23:38 sig_hashalgo: sha512
  1. list bridge addresses failed

執行“systemctl start docker.service”時報如下錯誤:

12月 18 16:26:19 X.site dockerd[23727]: failed to start daemon: Error initializing network controller: list bridge addresses failed: PredefinedLocalScopeDefaultNetworks List: [172.17.0.0/16 172.18.0.0/16 172.19.0.0/16 172.20.0.0/16 172.21.0.0/16 172.22.0.0/16 172.23.0.0/16 172.24.0.0/16 172.25.0.0/16 172.26.0.0/16 172.27.0.0/16 172.28.0.0/16 172.29.0.0/16 172.30.0.0/16 172.31.0.0/16 192.168.0.0/20 192.168.16.0/20 192.168.32.0/20 192.168.48.0/20 192.168.64.0/20 192.168.80.0/20 192.168.96.0/20 192.168.112.0/20 192.168.128.0/20 192.168.144.0/20 192.168.160.0/20 192.168.176.0/20 192.168.192.0/20 192.168.208.0/20 192.168.224.0/20 192.168.240.0/20]: no available network 12月 18 16:26:19 X.site systemd[1]: docker.service: main process exited, code=exited, status=1/FAILURE 12月 18 16:26:19 X.site systemd[1]: Failed to start Docker Application Container Engine. 12月 18 16:26:19 X.site systemd[1]: Unit docker.service entered failed state.

這個錯誤是因為沒有網橋(可執行命令“ip a”或“netstat
-ie”等檢查),導致docker無法啟動。執行以下命令創建和啟動網橋:

# ip link add name docker0 type bridge # ip addr add dev docker0 172.17.0.1/16 # ip link set docker0 up # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000 link/ether 60:eb:69:fe:2e:20 brd ff:ff:ff:ff:ff:ff 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000 link/ether 60:eb:69:fe:2e:21 brd ff:ff:ff:ff:ff:ff inet 10.22.25.101/26 brd 10.223.25.127 scope global eth1 valid_lft forever preferred_lft forever 4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN link/ether 6e:3c:cb:3e:a7:44 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 scope global docker0 valid_lft forever preferred_lft forever

創建網橋也可使用專門的工具brctl

  1. No module named yum

在執行yum命令時,如果報如下錯誤:

# yum There was a problem importing one of the Python modules required to run yum. The error leading to this problem was: No module named yum Please install a package which provides this module, or verify that the module is installed correctly. It's possible that the above module doesn't match the current version of Python, which is: 2.7.5 (default, Jun 17 2014, 18:11:42) [GCC 4.8.2 20140120 (Red Hat 4.8.2-16)] If you cannot solve this problem yourself, please go to the yum faq at: http://yum.baseurl.org/wiki/Faq

命令yum實為Python腳本,這個錯誤表示找不到名為yum的Python模塊。檢查Python的模塊搜索路徑:

# python Python 2.7.5 (default, Jun 17 2014, 18:11:42) [GCC 4.8.2 20140120 (Red Hat 4.8.2-16)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> print sys.path ['', '/usr/lib64/python27.zip', '/usr/lib64/python2.7', '/usr/lib64/python2.7/plat-linux2', '/usr/lib64/python2.7/lib-tk', '/usr/lib64/python2.7/lib-old', '/usr/lib64/python2.7/lib-dynload', '/usr/lib64/python2.7/site-packages', '/usr/lib64/python2.7/site-packages/gtk-2.0', '/usr/lib/python2.7/site-packages', '/usr/lib/python2.7/site-packages/setuptools-34.4.1-py2.7.egg', '/usr/lib/python2.7/site-packages/MySQL_python-1.2.5-py2.7-linux-x86_64.egg'] >>>

如果模塊yum可用,可通過如下方法找到它所有路徑:

# python >>> import yum >>> print yum._file_ /usr/lib/python2.7/site-packages/yum/init.pyc

如果模塊yum並不存在,則可從其它可用的機器復制一份過來,保持目錄一致。如果在執行“import
yum”報錯“No module named urlgrabber”和“No module named
rpmUtils.transaction”,則也需要將urlgrabber等模塊復制過來,直到“import
yum”不再報錯。

  1. rpmdb open failed

執行“yum install docker-ce-19.03.5-3.el7.x86_64.rpm”時報如下錯誤:

# yum install docker-ce-19.03.5-3.el7.x86_64.rpm error: rpmdb: BDB0113 Thread/process 7020/140405160273920 failed: BDB1507 Thread died in Berkeley DB library error: db5 error(-30973) from dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery error: cannot open Packages index using db5 - (-30973) error: cannot open Packages database in /var/lib/rpm CRITICAL:yum.main: Error: rpmdb open failed

這個錯誤是因為RPM數據庫損壞了,執行以下操作的修復:

# cd /var/lib/rpm # tar czf x.tar.gz __db.* # rm -f __db.* # rpm --rebuilddb # yum clean all

然后,可再次執行“yum install docker-ce-19.03.5-3.el7.x86_64.rpm”。

  1. start request repeated too quickly for docker.service

執行“systemctl start docker.service”時報如下錯誤:

systemd[1]: start request repeated too quickly for docker.service systemd[1]: Failed to start Docker Application Container Engine. systemd[1]: Unit docker.service entered failed state. systemd[1]: docker.service failed.

“systemctl start
docker.service”輸出的信息可能不全,可直接查看系統日志文件/var/log/messages,如果看到以下錯誤信息:

Running modprobe nf_nat failed with message: `modprobe: WARNING: Module nf_nat not found.`, error: exit status 1

該錯誤表示沒有加載內核模塊“iptable_nat”,執行“modinfo iptable_nat”確認:

# modinfo iptable_nat modinfo: ERROR: Module iptable_nat not found.
  1. Module nf_nat not found

該錯誤表示沒有加載內核模塊“iptable_nat”,模塊文件位於目錄/lib/modules/`uname
-r`/kernel/。

# ls /lib/modules/`uname -r`/kernel/ arch crypto drivers fs kernel lib mm net

內核模塊“iptable_nat”又依賴nf_nat和ip_tables等內核模塊,成功加載后問題將解決。

# lsmod | grep nat iptable_nat 13011 1 nf_nat_ipv4 13263 1 iptable_nat nf_nat 26711 3 ipt_MASQUERADE,nf_nat_ipv4,iptable_nat nf_conntrack 96187 8 ipt_MASQUERADE,nf_nat,nf_nat_ipv4,xt_conntrack,nf_conntrack_netlink,iptable_nat,nf_conntrack_ipv4,nf_conntrack_ipv6 ip_tables 27239 4 iptable_filter,iptable_mangle,iptable_nat,iptable_raw


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM