Docker安装与镜像,容器命令管理
docker和容器的關系
-Docker是完整的一套容器管理系統
-Docker提供了一組命令, 讓用戶更加方便直接地使用容器技 術,而不需要過多關心底層內核技術
一.Docker的安裝
1.配置環境變量
-需要64位操作系統
-至少RHEL6.5以上的版本,強烈推薦RHEL7(主要是因為內核限制,3.1以上即可)
-關閉防火墻(不是必須的)
2.docker的安裝
1)安裝前檢查
# 檢查內核與linux版本 ~]# hostnamectlStatic hostname: VM-0-51-centosIcon name: computer-vmChassis: vmMachine ID: 35b12e3f2e994abebdafc2f42fe653dfBoot ID: 816a7c7dd74a48b69fc74b0330106201Virtualization: kvmOperating System: CentOS Linux 7 (Core)CPE OS Name: cpe:/o:centos:centos:7Kernel: Linux 3.10.0-1127.19.1.el7.x86_64Architecture: x86-64 ? # 開啟路由轉發 ~]# vim /etc/sysctl.conf net.ipv4.ip_forward = 1 ~]# sysctl -p ? ## 運用阿里的yum源安裝 # 下載yum配置 ~]#wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 刷新并安裝 ~]# yum clean all && yum repolist && yum makecache注:因為容器里有一塊網卡docker0,如果eth0不設置路由轉發的話,他們之間也就無法轉發通信
2)安裝Docker
# 查看最新版本并安裝 ~]# yum list docker-ce --showduplicates | sort -r ~]# yum install -y docker-ce ? # 安裝成功后,使用docker version命令查看是否安裝成功,安裝成功后------如下 ~]# docker version Client:Version: ? ? ?17.05.0-ceAPI version: ?1.29Go version: ? go1.7.5Git commit: ? 89658beBuilt: ? ? ? Thu May ?4 22:06:25 2017OS/Arch: ? ? linux/amd64 Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?或則下載安裝包安裝
安裝包官方地址:Index of linux/static/stable/x86_64/
## 可以先下載到本地,然后通過ftp工具上傳到服務器上,或者在服務器上使用命令下載 ~]# wget https://download.docker.com/linux/static/stable/x86_64/docker-18.06.3-ce.tgz# 解壓 ~]# tar -zxvf docker-18.06.3-ce.tgz# 將解壓出來的docker文件復制到?/usr/bin/ 目錄下 ~]# cp docker/* /usr/bin/# 在/etc/systemd/system/目錄下新增docker.service文件,內容如下,這樣可以將docker注冊為service服務 ~]# vim /etc/systemd/system/docker.service [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service Wants=network-online.target[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 --selinux-enabled=false --insecure-registry=127.0.0.1 ExecReload=/bin/kill -s HUP $MAINPID # 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 # Uncomment TasksMax if your systemd version supports it. # Only systemd 226 and above support this version. #TasksMax=infinity TimeoutStartSec=0 # 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 # restart the docker process if it exits prematurely Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s[Install] WantedBy=multi-user.target# 此處的--insecure-registry=127.0.0.1(此處改成你私服ip)設置是針對有搭建了自己私服Harbor時允許docker進行不安全的訪問,否則訪問將會被拒絕。## 啟動docker # 給docker.service文件添加執行權限 ~]# chmod +x /etc/systemd/system/docker.service # 重新加載配置文件(每次有修改docker.service文件時都要重新加載下) ~]# systemctl daemon-reload ?3)啟動容器
~]# systemctl start docker.service ? # 驗證安裝是否成功(有client和service兩部分表示docker安裝啟動都成功了) ~]# docker version Client: Docker Engine - CommunityVersion: ? ? ? ? ? 18.09.9API version: ? ? ? 1.39Go version: ? ? ? go1.11.13Git commit: ? ? ? 039a7df9baBuilt: ? ? ? ? ? ? Wed Sep ?4 16:50:02 2019OS/Arch: ? ? ? ? ? linux/amd64Experimental: ? ? ?false ? Server: Docker Engine - CommunityEngine:Version: ? ? ? ? ?18.09.9API version: ? ? ?1.39 (minimum version 1.12)Go version: ? ? ? go1.11.13Git commit: ? ? ? 039a7df9baBuilt: ? ? ? ? ? Wed Sep ?4 16:55:50 2019OS/Arch: ? ? ? ? linux/amd64Experimental: ? ? false ? # 設置開機自啟動 ~]# systemctl enable docker二.鏡像與容器
Docker的三大核心概念:鏡像、容器、倉庫
1.鏡像
1)鏡像的概述
類似虛擬機的鏡像、用俗話說就是安裝文件。
\- 鏡像是啟動容器的核心- 在Docker中容器是基于鏡像啟動的
- 鏡像采用分層設計
-使用COW技術(寫實復制,最多只能是255層)
寫實復制:
Copy-On-Write簡稱COW,是一種用于程序設計中的優化策略。其基本思路是,從一開始大家都在共享同一個內容,當某個人想要修改這個內容的時候,才會真正把內容Copy出去形成一個新的內容然后再改,這是一種延時懶惰策略
什么是CopyOnWrite容器:
CopyOnWrite容器即寫時復制的容器。通俗的理解是當我們往一個容器添加元素的時候,不直接往當前容器添加,而是先將當前容器進行Copy,復制出一個新的容器,然后新的容器里添加元素,添加完元素之后,再將原容器的引用指向新的容器。這樣做的好處是我們可以對CopyOnWrite容器進行并發的讀,而不需要加鎖,因為當前容器不會添加任何元素。所以CopyOnWrite容器也是一種讀寫分離的思想,讀和寫不同的容器
注:所以說容器是基于鏡像的讀寫層創建的
2)獲取鏡像
-官方倉庫下載或自己制作
-官方倉庫
Docker Hub
# 如果下不了國外的鏡像也可以設置國內的(daemon.json文件需自己創建) ~]# vim /etc/docker/daemon.json {"registry-mirrors": ["https://registry.docker-cn.com", "http://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn"]} ~]# systemctl restart docker.service # 重啟生效3)鏡像的管理命令
| docker images | 查看鏡像 | |
| docker search 關鍵字 | 查找鏡像 | 默認查看國外的 |
| docker pull 鏡像名稱 | 下載鏡像 | |
| docker push 鏡像名稱:鏡像標簽 倉庫地址 | ||
| docker save 鏡像名稱:鏡像標簽 -o 文件名(tar 格式) | 備份鏡像(導出鏡像) | |
| docker load -i 備份文件名稱(.tar) | 恢復鏡像(導入鏡像) | |
| docker inspect 鏡像名稱:鏡像標簽 | 查看鏡像詳細信息 | |
| docker history 鏡像名稱:鏡像標簽 | 查看鏡像的層(制作歷史) | |
| docker tag 鏡像名稱:鏡像標簽 (舊的) 鏡像名稱:鏡像標簽(新得) | 給鏡像添加新的名稱和標簽 | |
| docker rmi 鏡像名稱:鏡像標簽 | 刪除鏡像 | 要先停止容器 |
4)示例
# 查找鏡像(默認從官網找) ~]# docker search centos NAME ? ? ? DESCRIPTION ? ? ? ? ? ? ? ? STARS ? ? ? ? ? ? ? OFFICIAL ? ? ? ? ? AUTOMATED centos ? The official build of CentOS. ? 6963 ? ? ? ? ? ? ? [OK] ? ? ? ? ? ? ? ? ansible/centos7-ansible Ansible on Centos7 ? ? ? ? ?135 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [OK] consol/centos-xfce-vnc ? ? ? ? ? Centos container with "headless" VNC session… ? 132 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [OK] # 下載鏡像 ~]# docker pull centos ..... Status: Downloaded newer image for centos:latest ? # 上傳鏡像 ~]# docker push centos:latest 倉庫地址| 鏡像的名字 | 鏡像的簡單描述 | 鏡像被點贊的次數 | 代表是否是由官方提供的 |
| 鏡像名稱 | 鏡像標簽 | 鏡像ID | 鏡像的創建時間 | 鏡像的大小 |
5)鏡像的名稱和標簽的概述
-
每一個鏡像都對應唯一的鏡像 id
-
鏡像名稱(文件名稱)+標簽 (路徑) ==唯一
-
每一個鏡像都有標簽,如果沒寫就是默認標簽 latest
-
我們在調用鏡像的時候,如果沒有指定標簽也是 latest
2.容器
類似一個輕量級的沙箱,容器是從鏡像創建應用運行實例,
可以將其啟動、開始、停止、刪除、而這些容器都是相互隔離、互不可見的。
1)容器的管理命令
| docker run -it(d) 鏡像名稱:標簽 啟動命令 | 創建啟動并進入容器,后臺容器使用參數d |
| docker ps | 查看容器-a所有容器,包含未啟動的,-q只顯示id |
| docker rm 容器ID | -f強制刪除,支持命令重入 |
| docker start|stop|restart 容器id | 啟動、停止、重啟容器 |
| docker cp 本機文件路徑 容器id:容器內路徑 | 把本機文件拷貝到容器(上傳) |
| docker cp 容器id:容器內路徑 本機文件路徑 | 從容器內拷貝文件到宿主機(下載) |
| docker inspect 容器ID | 查看容器詳細信息 |
| docker attach 容器id | 進入容器默認進程,推出后關閉默認進程(變相關閉容器) |
| docker attach 容器id{ctr+p,ctl+q} | 進入容器以后,退出容器而不關閉的方法 |
| docker exec -it 容器id 啟動命令 | 進入容器新的進程,推出后容器不會關閉 |
2)docker run命令參數
docker run 命令
-docker run -參數 鏡像名稱:鏡像標簽 啟動命令
查看 run的參數
-docker help run
run = 創建+啟動+進入
-
參數 -i,交互式
- 參數 -t,終端
- 參數 -d,后臺運行
- 參數 --name 容器名字
示例
# 啟動centos 容器,并進入容器 ~]# docker run -it centos:latest /bin/bash ~]# exit #退出后容器自動關閉(使用ctrl+p,Ctrl+q # 使用快捷鍵退出,保證容器不關閉) ## 啟動命令 # 但不知道啟動命令時則不寫(不寫則用默認的) ~]# docker run -it centos # 當寫了啟動命令時就不會執行默認的, # 默認的用處比如應用程序容器nginx,apache等 ~]# docker run -it nginx:latest #此時是不可以交互的,直接退出會關閉容器(可以使用快捷鍵退出,放入后臺),但此時多次一舉不如直接放入后臺 ~]# docker run -itd nginx:latest ~]# ps -ef ..... root 25795 12099 0 16:42 ? 00:00:00 containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/753ff4121bdac92221be3)示例
## 查看容器 # 查看啟動的容器 ~]# docker ps# 查看所有容器,包含未啟動的 ~]# docker ps -a# 只查看啟動容器的id ~]# docker ps -q # 查看所有容器的id ~]# docker ps -aq ## 刪除容器 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 753ff4121bda centos "/bin/bash" 45 minutes ago Up 45 minutes vigilant_payne # 正常刪除 ~]# docker rm 753ff4121bda# 當容器還是啟動時則不能正常刪除,需停止容器再刪除 ~]# docker stop 753ff4121bda ~]# docker rm 753ff4121bda# 強制刪除(會損壞數據,如運行時的數據庫,會損壞表庫等) ~]# docker rm -f 753ff4121bda# 刪除所有容器 ~]# docker rm $(docker stop $(docker ps -aq)) ## 啟動、停止、重啟容器 # 格式 docker start|stop|restart 容器ID|容器名字 ~]# docker start 753ff4121bda|vigilant_payne ~]# docker stop 753ff4121bda|vigilant_payne ~]# docker restart 753ff4121bda|vigilant_payne ## 查看容器詳細信息 # 格式 ~]# docker inspect 容器ID|容器名字 ~]# docker inspect vigilant_payne [ ........ "NetworkSettings": {"Bridge": "","SandboxID": "4640bfda49bca0c2fe676cd805150bed1521a8da84f0968f7184ecb9864f1c19","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/4640bfda49bc","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "cf4686443b5ccfe73609cdcb6ff3381f944fe84bf9bb96cb02aedbec11881381","Gateway": "172.18.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.18.0.5","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:12:00:05","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "a98aa42f05e6d61e49409a1411c93dc65db871eec3c0518acab20d42e938a858","EndpointID": "cf4686443b5ccfe73609cdcb6ff3381f944fe84bf9bb96cb02aedbec11881381","Gateway": "172.18.0.1","IPAddress": "172.18.0.5","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:12:00:05","DriverOpts": null}}}} ] # 注:有用的信息如上,網絡配置只有啟動容器才有 ## 從容器內拷貝首頁文件到宿主機,修改后拷貝回容器內# 下載格式 ~]# docker cp 容器ID:容器路徑 本機文件路徑 ~]# docker cp 9cae0af944d8:/usr/share/nginx/html/index.html ./index.html ~]# vim index.html Hello Tedu Hello Tedu Hello Tedu# 上傳格式 ~]# docker cp 本機文件路徑 容器id:容器內路徑 ~]# docker cp ./index.html 9cae0af944d8:/usr/share/nginx/html/index.html # 測試 剛剛的詳細信息可查看IP地址 ~]# curl http://172.18.0.5/ ## 啟動容器 # 使用 attach啟動(可以不帶啟動命令) ~]# docker attach 753ff4121bda #注:推出后容器會關閉(解決翻案快捷鍵ctl+p,ctl+q),只能進入有交互式的容器,入nginx的應用服務則不會動 /]# ctl+p,ctl+q >> read escape sequence# 使用exec(必須帶啟動命令) ~]# docker exec -it 753ff4121bda /bin/bash # 退出后不會關閉容器,可以進入任意容器#注:attach連接的是容器的啟動進程(主要用于排錯)而exec進入的則是新進程(主要用于維護管理) ~]# docker attach 753ff4121bda # 此時啥也沒有~]# curl http://172.18.0.5/haha.html curl: (7) Failed connect to 172.18.0.5:80; Connection refused # 此時容器內就會報錯三.容器的進程管理
1.上帝進程的概述
簡單的說就是系統創建之初產生的第一個進程
特點:
-沒有父進程
-PID==1
-所有進程都是他的子進程,孫子進程,曾孫,玄孫進程
-上帝進程死亡系統實例也就不存在
2.上帝進程與容器的關系
容器的啟動進程就是上帝進程,他的pid==1
上帝進程退出==容器關閉
如何保證容器不關閉?
-容器的啟動進程不能被關閉
-容器的啟動進程必須在前臺運行
前臺服務與后臺服務
容器的啟動進程在后臺運行不等于容器在后臺運行
容器的啟動服務
-前臺服務(-it)
????????一般能與用戶交互的程序,比如/bin/bash /bin/sh
-后臺服務(-itd)
????????一般是一個程序的服務,比如apache、nginx、redis等
示例
# 查看該容器的啟動進程 /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 09:35 pts/0 00:00:00 /bin/bash # 查看當前進程 /]# echo $$ 1 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 753ff4121bda centos "/bin/bash" 3 hours ago Exited (0) 2 seconds ago vigilant_payne3.僵尸進程與孤兒進程的基本概念
我們知道在unix/linux中,正常情況下,子進程是通過父進程創建的,子進程在創建新的進程。子進程的結束和父進程的運行是一個異步過程,即父進程永遠無法預測子進程 到底什么時候結束。 當一個 進程完成它的工作終止之后,它的父進程需要調用wait()或者waitpid()系統調用取得子進程的終止狀態。
孤兒進程:
一個父進程退出,而它的一個或多個子進程還在運行,那么那些子進程將成為孤兒進程。孤兒進程將被init進程(進程號為1)所收養,并由init進程對它們完成狀態收集工作。
僵尸進程:
一個進程使用fork創建子進程,如果子進程退出,而父進程并沒有調用wait或waitpid獲取子進程的狀態信息,那么子進程的進程描述符仍然保存在系統中。這種進程稱之為僵死進程。
問題及危害
unix提供了一種機制可以保證只要父進程想知道子進程結束時的狀態信息, 就可以得到。這種機制就是: 在每個進程退出的時候,內核釋放該進程所有的資源,包括打開的文件,占用的內存等。 但是仍然為其保留一定的信息(包括進程號the process ID,退出狀態the termination status of the process,運行時間the amount of CPU time taken by the process等)。直到父進程通過wait / waitpid來取時才釋放。 但這樣就導致了問題,如果進程不調用wait / waitpid的話, 那么保留的那段信息就不會釋放,其進程號就會一直被占用,但是系統所能使用的進程號是有限的,如果大量的產生僵死進程,將因為沒有可用的進程號而導致系統不能產生新的進程. 此即為僵尸進程的危害,應當避免。
孤兒進程是沒有父進程的進程,孤兒進程這個重任就落到了init進程身上,init進程就好像是一個民政局,專門負責處理孤兒進程的善后工作。每當出現一個孤兒進程的時候,內核就把孤 兒進程的父進程設置為init,而init進程會循環地wait()它的已經退出的子進程。這樣,當一個孤兒進程凄涼地結束了其生命周期的時候,init進程就會代表黨和政府出面處理它的一切善后工作。因此孤兒進程并不會有什么危害。
任何一個子進程(init除外)在exit()之后,并非馬上就消失掉,而是留下一個稱為僵尸進程(Zombie)的數據結構,等待父進程處理。這是每個 子進程在結束時都要經過的階段。如果子進程在exit()之后,父進程沒有來得及處理,這時用ps命令就能看到子進程的狀態是“Z”。如果父進程能及時 處理,可能用ps命令就來不及看到子進程的僵尸狀態,但這并不等于子進程不經過僵尸狀態。 如果父進程在子進程結束之前退出,則子進程將由init接管。init將會以父進程的身份對僵尸狀態的子進程進行處理。
僵尸進程危害場景:
例如有個進程,它定期的產 生一個子進程,這個子進程需要做的事情很少,做完它該做的事情之后就退出了,因此這個子進程的生命周期很短,但是,父進程只管生成新的子進程,至于子進程 退出之后的事情,則一概不聞不問,這樣,系統運行上一段時間之后,系統中就會存在很多的僵死進程,倘若用ps命令查看的話,就會看到很多狀態為Z的進程。 嚴格地來說,僵死進程并不是問題的根源,罪魁禍首是產生出大量僵死進程的那個父進程。因此,當我們尋求如何消滅系統中大量的僵死進程時,答案就是把產生大 量僵死進程的那個元兇槍斃掉(也就是通過kill發送SIGTERM或者SIGKILL信號啦)。槍斃了元兇進程之后,它產生的僵死進程就變成了孤兒進 程,這些孤兒進程會被init進程接管,init進程會wait()這些孤兒進程,釋放它們占用的系統進程表中的資源,這樣,這些已經僵死的孤兒進程 就能瞑目而去了。
4.服務在前臺運行實驗
1)容器內安裝apache服務
# 刪除所有容器(防止影響測試) ~]# docker rm -f $(docker ps -aq) # 啟動一個容器 ~]# docker run -it --name myapache centos:latest # 搭建yum倉庫,由于容器是與宿主機共享資源的,直接可以用宿主機的配置 /]# cd /etc/yum.repos.d/ && rm -rf *.repo # --------------不要退出這個終端,在另一個終端拷貝 yum 配置文件到容器-------------------- ~]# cp /etc/yum.repos.d/CentOS-Base.repo myapache:/etc/yum.repos.d/ #------------------------回到創建容器的終端繼續執行命令--------------------- # 安裝軟件 /]# yum install -y net-tools httpd # 寫一個默認網頁 /]# echo Hello world >/var/www/html/index.html## 由于容器內么有systemd進程所以只能用手動啟動啟動 /]# ps -ef #可以看出沒有systemd進程 UID PID PPID C STIME TTY TIME CMD root 1 0 0 09:35 pts/0 00:00:00 /bin/bash root 31 1 0 11:11 pts/0 00:00:00 ps -ef # 查看服務的啟動參數 ~]# cat /usr/lib/systemd/system/httpd.service ..... ExecStart=/usr/sbin/httpd -D $OPTIONS -DFOREGROUND ....... # 可以發現有一個環境變量,此時查看 ~]# cat /etc/sysconfig/httpd ...... #OPTIONS= .... LANG=C .... # 配置環境變量 /]# export LANG=C # 查看網卡ip /]# ifconfig ..... ...172.17.0.2... ..... # 手動啟動 /]# /usr/sbin/httpd -DFOREGROUND # 此時會發現會占用此終端(ctl+p,ctl+q) # 訪問測試 ~]# curl http://172.17.0.2/ Hello world總結
管理鏡像使用 名稱:標簽
管理容器使用 **容器ID
總結
以上是生活随笔為你收集整理的Docker安装与镜像,容器命令管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 公有云 --- 华为云的基本运用
- 下一篇: Docker进阶(制作镜像,共享卷,网络