Docker原理解讀
1262
2025-03-31
寫在前面
筆記內容:由理論和具體docker常用操作構成。
這篇博文筆記的定位是:溫習,查閱,不適合新手學習。
你擁有青春的時候,就要感受它,不要虛擲你的黃金時代,不要去傾聽枯燥乏味的東西,不要設法挽留無望的失敗,不要把你的生命獻給無知,平庸和低俗。 ------王爾德
一、docker 原理
關于docker,容器這些,舉一個很簡單的例子,啟動盤,有時候我們
Docker 是完整的一套容器管理系統,所以想要搞懂 Docker 的概念,我們必須先從容器開始說
起。什么是容器?
容器是用來裝東西的,Linux 里面的容器是用來裝應用的;
容器就是將軟件打包成標準化單元,以用于開發、交付和部署;
容器技術已經成為應用程序封裝和交付的核心技術;
容器技術的核心,由以下幾個內核技術組成:
Cgroups (Control Groups)?— 資源管理
SELinux?— 安全 (是針對于文件系統,文件的管理措施)
NameSpace?— 命名空間
是指可以對系統資源空間進行分割隔離的技術,例如:創建一個虛擬機,在虛擬機里的所有操
作,都不會對真實機造成影響。
命名空間分為六大類,可以從各個方面來對系統資源空間進行隔離;
UTS:主機名命名空間,作用:分割主機名,即在容器內修改主機名,不會對宿主機的系統造成影響,實現主機名的隔離;
NETWORK:網絡命名空間,作用:分割網絡,即容器內的網絡配置和宿主機相互之間不受干擾的;例如在真實機器上的網卡名為eth0,IP地址為192.168.1.10/24;而在容器內的網卡名可以為ens33,ip地址為10.10.10.10/24;
MOUNT:掛載命名空間,作用:隔離文件系統,在容器內掛載的光盤或nfs共享目錄,宿主機是無法看到里面的內
容的;例如:在linux系統上,創建一個虛擬機,在真機的/var/lib/ftp中掛載了一個光盤文件,但是在虛擬機的/var/lib/ftp中是沒有光盤內容的,這就是MOUNT隔離;
USER:用戶命名空間,作用:隔離用戶,即容器內創建的用戶不能用于登錄宿主機,真機機里創建的用戶也不能
作用于容器;
PID:進程命名空間,作用:為了防止容器和宿主機中的進程沖突;例如:在真實機中,有一個服務: nfs,PID為2250;在容器內,也有一個服務: chrony,PID為2250;真實機中用戶,殺死(kill) PID號為2250的進程時,并不會對容器內的進程2250產生影響;而容器內的用戶,殺死(kill) PID號為2250的進程時,也并不會對真實機內的進程2250產生影響;
IPC:信號向量命名空間,作用:通常和PID一起使用;用戶殺死一個進程時,實際上是向進程發送一個信號(IPC),進程接收到這個信號后會執行對應的操作;
docker 的特性
優點:相比于傳統的虛擬化技術,容器更加簡潔高效,傳統虛擬機需要給每個 VM 安裝操作系統,容器使用的共享公共庫和程序
缺點:容器的隔離性沒有虛擬機強共用Linux內核,安全性有先天缺陷.
docker 與傳統虛擬化的對比:
虛擬化:例如:虛擬機的使用,每一個虛擬機都要安裝獨立的操作系統;將一臺服務器轉變為多臺服務器的物理硬件的抽象。系統管理程序允許多個VM在單臺計算機上運行。每個VM包含操作系統,應用程序,必要的二進制文件和庫的完整副本-占用數十GB。VM也可能啟動緩慢。
容器:不需要安裝獨立的操作系統,只有一個Docker進程,和宿主機共享操作系統;容器沒有操作系統,啟動容器就跟開啟一個進程一樣,簡單高效;是應用程序層的抽象,將代碼和依賴項打包在一起。多個容器可以在同一臺計算機上運行, 并與其他容器共享OS內核,每個容器在用戶空間中作為隔離的進程運行。容器占用的空間少于VM(容器映像的大小通常為幾十MB),可以處理更多的應用程序,并且需要的VM和操作系統更少。
運行區別( 容器的高效性):
啟動虛擬機中的應用程序,需要先啟動虛擬機的操作系統,然后再啟動應用程序;
啟動容器內的應用程序,直接啟動應用程序即可;
二、docker 安裝部署
docker安裝
需要64位操作系統,至少 RHEL6.5 以上的版本,強烈推薦 RHEL7
docker安裝時,內核要求在3.0以上,RHEL7的內核默認在3.0以上,不滿足可以單獨升級系統內核。
查看linux系統的內核版本,【uname -r】也可以
關閉防火墻 (不是必須):firewalld【RHEL7使用】,Iptables【RHEL6使用】,Docker安裝時,會自動的接管防火墻,并向防火墻里添加配置,如果防火墻存在,會產生沖突。
配置 yum 源
在物理機的 http 目錄下創建文件夾 extras: mkdir /var/www/html/extras
把光盤掛到這個目錄下 : mount -t iso9660 -o ro,loop RHEL70OSP-extras.iso /var/www/html/extras
卸載防火墻?yum remove -y firewalld-*
安裝軟件包?yum install docker
開啟路由轉發?/etc/sysctl.conf net.ipv4.ip_forward=1?使用sysctl -p讓配置立刻生效(否則需要重新虛擬機)docker是通過虛擬交互機來進行通訊的,需要開啟路由轉發的功能。
軟件的 BUG?:iptables -nL FORWARD?版本 大于 1.12 時會設置 FORWARD 的默認規則,被設置為 DROP,對于有些docker的版本中,FORWARD鏈的規則被設置成了DROP,會造成容器和宿主機之間無法通訊。
解決辦法:
修改 /lib/systemd/system/docker.server
重載配置文件,重啟服務?systemctl daemon-reload systemctl restart docker
[root@liruilong ~]# systemctl daemon-reload [root@liruilong ~]# systemctl restart docker
三、獲取鏡像
鏡像、容器、倉庫
鏡像是啟動容器的核心,在Docker?中容器是基于鏡像啟動的,鏡像采用分層設計,使用COW技術
容器本身是沒有操作系統,和宿主機共用一個操作系統;
容器是docker(容器的管理工具)使用鏡像文件來啟動的;
鏡像是啟動容器的模板,鏡像中存放的是應用程序(服務軟件),例如: 有一個http的鏡像文件,在這個鏡像中就存放的是http的所有文件和變量;
用戶使用鏡像啟動容器時,會生成一個獨立于鏡像的容器層,并不會對鏡像層產生任何影響;
而且容器采用了cow(寫時復制)的技術,用戶可以使用一個鏡像文件創建多個容器,互不干擾;
鏡像采用分層技術:用戶可以根據自己的需求來制作鏡像,例如:在鏡像的第一層定義應用程序的變量,在鏡像的第二層修改配置文件,在鏡像的第三層進行應用軟件的部署;分層做好鏡像后,用戶使用鏡像啟動容器時,可以選擇根據鏡像的哪一層來啟動,類似快照還原;
鏡像可以從官方鏡像倉庫下載,也可以自己制作
官方鏡像倉庫:https://hub.docker.com
查看本機鏡像?docker images
#REPOSITORY?鏡像名稱
#TAG?鏡像標簽
#IMAGE ID?鏡像ID號
#CREATED?鏡像創建時間
#SIZE?鏡像大小
#INDEX?索引名稱,即網站域名
#NAME?鏡像的名稱
#DESCRIPTION?鏡像的描述信息
#STARS?鏡像被下載的次數
#OFFICIAL?是否是docker官方開發的
#AUTOMATED?是否自動構建鏡像
鏡像busybox,需要指定名字和標簽,導出到/root目錄下,名稱為busybox.tar
[root@kube-node1 ~]$ docker save docker.io/busybox:latest -o /root/busybox.tar
拷貝備份鏡像到其他機器上
[root@kube-node1 ~]$ scp /root/busybox.tar 192.168.1.22:/root/
docker load -i busybox.tar
四、第一個容器
運行容器
鏡像名稱:鏡像標簽這種形式,可以指定唯一的鏡像,防止鏡像名相同,內容不同的情況,latest為默認標簽,創建鏡像時,不指定標簽,則為此默認標簽
+run?=?創建?+?啟動?+進入,docker run 命令: 運行過程中,會先根據鏡像來創建容器,然后會啟動容器,最后進入容器
幫助文檔:查看 run 的參數:?docker help run?man docker-run
參數:?-i?交互式,-t終端,-d?后臺運行,?--name?容器名字 :docker run -it docker.io/centos:lasest /bin/bash(#/bin/bash為容器內的命令,容器內存在,才可以使用)
五、docker 鏡像管理
鏡像管理命令
查看鏡像:?docker images
查找鏡像?docker search
刪除鏡像?docker rmi 鏡像名稱:鏡像標簽?&&?docker image rm fd1c5f7b6816
下載鏡像?docker pull 鏡像名稱: 鏡像標簽
上傳鏡像?docker push 要上傳的鏡像名稱: 鏡像標簽
備份鏡像?docker save 鏡像名稱: 鏡像標簽 -o 備份文件名稱
恢復鏡像?docker load -i 備份文件名稱
查看鏡像的制作歷史?docker history 鏡像名稱: 鏡像標簽
查看鏡像的信息?docker inspect 鏡像名稱: 鏡像標簽
鏡像的新名稱和標簽?docker tag 鏡像名稱: 鏡像標簽 新鏡像名稱: 新的標簽
六、docker 容器管理
常用容器管理命令
啟動容器?docker run -參數 鏡像名稱:鏡像標簽 啟動命令
查看容器?docker ps [ -a 所有容器id ] [ -q 只顯示容器 id ]
刪除容器?docker rm 容器id、
容器管理啟動?docker start 容器id
容器管理停止?docker stop 容器id
容器管理重啟?docker restart 容器id
查看容器進程?docker top 容器id
查看容器信息?docker inspect 容器id
連接容器啟動進程?docker attach 容器id
attach?以上帝進程的身份,進入容器內部,使用attach進入容器,是上帝進程的身份進入容器的,當執行exit退出容器時,會結束整個容器,查看進程樹,systemd就是上帝進程,即:系統服務的最初進程,所有的進程都是在上帝進程下創建的;當systemd進程被結束時,整個系統也就會崩潰通常用于在測試時,查看報錯信息;
連接容器,啟動新進程?docker exec -it 容器id 命令
在對容器的使用過程中,都是使用exec,新開一個進程的方式進入容器,進行編輯的;而attach?往往應用于調試,終端輸出的情況;
七,自定義鏡像
commit 自定義鏡像
自定義鏡像原理 :鏡像采用分層設計:1,創建讀寫層?2,修改配置?3,重新打包
使用鏡像啟動容器,在該容器基礎上修改,另存為一個新鏡像
docker run -it docker.io/centos:latest /bin/bash
配置 yum,安裝軟件,系統配置
docker commit 容器id 新鏡像名稱: 新鏡像標簽
############## 創建一個centos的容器,在kube-node1上操作 ############## ##查看所有的鏡像 [root@kube-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE busybox test 6858809bf669 5 weeks ago 1.232 MB docker.io/busybox latest 6858809bf669 5 weeks ago 1.232 MB docker.io/redis latest 82629e941a38 21 months ago 4.98 MB docker.io/nginx latest 42b4762643dc 21 months ago 109.2 MB docker.io/ubuntu latest 20bb25d32758 21 months ago 87.47 MB docker.io/centos latest 76d6bc25b8a5 2 years ago 199.7 MB ##-it 以交互式終端的方式,根據centos鏡像啟動一個容器 ##/bin/bash 為容器內的命令,容器內存在,才可以使用 [root@kube-node1 ~]# docker run -it docker.io/centos:latest /bin/bashh ################ 容器內安裝yum, 在kube-node1上操作 ############## #清除網絡yum文件,配置本地yum [root@d76e8f39e026 /]# rm -rf /etc/yum.repos.d/* [root@d76e8f39e026 /]# vi /etc/yum.repos.d/centos7.repo [centos] name=centos7.5 baseurl=http://192.168.1.100/centos-1804 enabled=1 gpgcheck=0 ##清空緩存,重新加載配置 [root@d76e8f39e026 /]# yum clean all [root@d76e8f39e026 /]# yum repolist ........ Determining fastest mirrors centos | 3.6 kB 00:00 (1/2): centos/group_gz | 166 kB 00:00 (2/2): centos/primary_db | 5.9 MB 00:00 repo id repo name status centos centos7.5 9911 repolist: 9911
################ 容器內安裝基礎工具軟件包, 在kube-node1上操作 ############## ##安裝基礎工具軟件包 [root@d76e8f39e026 /]# yum -y install net-tools psmisc iproute vim bashcompletion tree ##清除yum緩存,減小容器大小,用于鏡像制作 [root@d76e8f39e026 /]# yum clean all ##退出容器,主機名就是容器的ID號 [root@d76e8f39e026 /]# exit
################# commit自定義鏡像,在kube-node1上操作 ############## ##commit 提交容器,生成新的鏡像;此ID為容器的ID號 [root@kube-node1 ~]# docker commit d76e8f39e026 myos:latest sha256:10a665c54e587d47756a00058abef86ef6b329b44937aaea34376482c9410878 ##myos鏡像,就是新生成的鏡像 [root@kube-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myos latest 10a665c54e58 About a minute ago 317.8 MB ........
使用 docker run 驗證新的鏡像
############## 驗證新的鏡像,在kube-node1上操作 ############## ##查看歷史鏡像,多出一個鏡像層 [root@kube-node1 ~]# docker history myos:latest IMAGE CREATED CREATED BY SIZE COMMENT 10a665c54e58 3 minutes ago /bin/bash 118.1 MB ....... ##使用新的鏡像生成一個容器,容器的yum已經部署,驗證成功 [root@kube-node1 ~]# docker run -it myos:latest /bin/bash [root@5dbc2153d039 /]# yum repolist Loaded plugins: fastestmirror, ovl Loading mirror speeds from cached hostfile repo id repo name status centos centos7.5 9911 repolist: 9911
Dockerfile 自定義鏡像
語法
FROM:基礎鏡像
RUN:制作鏡像時執行的命令,可以有多個
ADD:復制文件到鏡像,自動解壓 (文件類型為: tar.gz 或 tar.bz2)
COPY:復制文件到鏡像,不解壓
MAINTAINER:鏡像創建者信息
EXPOSE:開放的端口
ENV:設置變量
WORKDIR:定義容器默認工作目錄
CMD: 容器啟動時執行的命令,僅可以有一條CMD.
ENTRYPOINT:類似CMD指令的功能,用于為容器指定默認運行程序,從而使得容器像是一具單獨的可執行程序
與CMD不同的是,由ENTRYPOINT啟動的程序不會被docker run命令行指定的參數所覆蓋,而且,這些命令行參數會被當作參數傳遞給ENTRYPOINT指定的程序。不過,docker run命令的–entrypoint?選項的參數可覆蓋ENTRYPOINT指令指定的程序
Dockerfile 案例1
配置 yum、安裝軟件
FROM docker.io/centos:latest RUN rm -f /etc/yum.repos.d/* COPY local.repo /etc/yum.repos.d/local.repo RUN yum install -y bash-completion net-tools iproute psmisc
創建鏡像
使用?Dockerfile?工作流程,根據Dockerfile生成新的鏡像,build創建新的鏡像;-t指定新鏡像的名字和標簽;. 指定Dockerfile文件所在的目錄
mkdir build
cd build
編寫 Dockerfile
########### 獲取制作鏡像的歷史命令,在kube-node1上操作 ############## ##利用myos鏡像,創建一個容器,可以查看之前制作鏡像的歷史命令 [root@kube-node1 ~]# docker run -it myos:latest docker build -t imagename Dockerfile 所在目錄 [root@096875f0df8d /]# history 1 rm -rf /etc/yum.repos.d/* 2 vi /etc/yum.repos.d/centos7.repo 3 yum clean all 4 yum repolist 5 yum -y install net-tools psmisc vim iproute vim bash-completiono tree 6 exit 7 history ##exit 退出,并關閉容器 [root@096875f0df8d /]# exit
########## 制作Dockerfile自動創建鏡像腳本,在kube-node1上操作 ############## ##創建一個目錄,名稱任意定義 [root@kube-node1 ~]# mkdir aa ##進入到aa目錄下 [root@kube-node1 ~]# cd aa/ ##創建Dockerfile文件,文件名不能改變 [root@kube-node1 ~]# touch Dockerfile ##復制repo文件到aa目錄下,用戶Dockerfile中的文件復制 [root@kube-node1 aa]# cp /etc/yum.repos.d/centos7.repo . ##編寫Dockerfile文件,文件名不能改變 ##Dockerfile中所有的指令,必須是大寫的(例如: FROM, RUN, COPY等) #FROM 指定基礎鏡像,Dockerfile會對基礎鏡像進行編輯,生成新的鏡像 #RUN 指定制作命令, 一條RUN,就代表一條要在容器內執行的命令 #COPY 復制,#即把當前目錄下的文件,拷貝到容器內 [root@kube-node1 aa]# vim Dockerfile FROM docker.io/centos:latest RUN rm -rf /etc/yum.repos.d/* COPY centos7.repo /etc/yum.repos.d/centos7.repo RUN yum -y install net-tools psmisc vim iproute vim bash-completiono tree && yum clean all
docker build -t imagename Dockerfile 所在目錄
########### 根據Dockerfile生成新的鏡像,在kube-node1上操作 ############ ##build 創建新的鏡像;-t 指定新鏡像的名字和標簽;. 指定Dockerfile文件所在的目錄 [root@kube-node1 aa]# docker build -t newos:latest . Sending build context to Docker daemon 3.072 kB Step 1 : FROM docker.io/centos:latest ---> 76d6bc25b8a5 Step 2 : RUN rm -rf /etc/yum.repos.d/* ---> Running in ade538eaf11c ---> a934f7feea65 Removing intermediate container ade538eaf11c Step 3 : COPY centos7.repo /etc/yum.repos.d/centos7.repo ---> bd5e3914cda6 Removing intermediate container 80ea3d53088e Step 4 : RUN yum -y install net-tools psmisc vim iproute vim bash-completiono tree && yum clean all ........ ##查看本地倉庫鏡像,newos創建成功 [root@kube-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE newos latest fb3d85796504 33 minutes ago 280.8 MB myos latest 10a665c54e58 58 minutes ago 317.8 MB .......
八,Dockerfile 入門
Dockerfile 創建服務鏡像
Dockfile中,不指定CMD時,則使用默認的啟動命令;如果沒有使用CMD指定啟動命令,則會繼承上一個鏡像的默認啟動命令;CMD?容器的默認啟動命令,有且只能有一條;
FROM myos:latest MAINTAINER Jacob redhat@163.com RUN yum -y install httpd ENV LANG=C WORKDIR /var/www/html/ EXPOSE 80 443 CMD ["httpd", "-DFOREGROUND"]
######## WORKDIR 在Dockerfile中用于定義容器默認工作目錄 ########### #使用ssh遠程執行以下三條命令,f1和f2文件,最終都是創建在/root目錄下 #因為每次ssh連接都是代表不同的連接,無法保持上次連接時,命令的執行狀態 [root@localhost ~]# ssh host1 touch f1 [root@localhost ~]# ssh host1 cd /tmp [root@localhost ~]# ssh host1 touch f2 ##### Dockerfile和ssh類似,所以要使用 WORKDIR容器默認工作目錄的指定 #####
###### 使用myos鏡像創建一個容器,在kube-node1上操作 ############ ##查看本地倉庫鏡像,myos鏡像已經部署好了yum和基本軟件包 [root@kube-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myos latest 10a665c54e58 58 minutes ago 317.8 MB ....... ####-it 以交互式終端的方式,根據centos鏡像啟動一個容器 ##/bin/bash 為容器內的命令,容器內存在,才可以使用,不指定則會選擇默認容器命令 [root@kube-node1 ~]# docker run -it myos:latest /bin/bash [root@a670096c60ad /]#
############ 部署并啟動apache服務,在kube-node1上操作 ############ ####安裝apache的服務軟件httpd [root@a670096c60ad /]# yum -y install httpd #因為容器內并沒有systemd的服務,無法使用systemctl來啟動httpd的服務 #查看httpd的服務文件,獲取環境變量文件和服務啟動命令 [root@a670096c60ad /]# cat /lib/systemd/system/httpd.service ........ [Service] ........ #環境變量文件 EnvironmentFile=/etc/sysconfig/httpd #啟動命令,$OPTIONS 此環境變量為空,可以不用寫 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND ........ ####從環境變量文件中,獲取環境變量 [root@a670096c60ad /]# vim /etc/sysconfig/httpd ...... LANG=C ####設置環境變量 [root@a670096c60ad /]# LANG=C #啟動httpd服務,$OPTIONS 此環境變量為空,可以不用寫 #Ctrl + C 退出 [root@54cb8bfa063d /]# /usr/sbin/httpd -DFOREGROUND AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
########## 制作Dockerfile自動創建鏡像腳本,在kube-node1上操作 ########### ##創建一個目錄,名稱任意定義 [root@kube-node1 ~]# mkdir bb ##進入到aa目錄下 [root@kube-node1 ~]# cd bb/ ##創建Dockerfile文件,文件名不能改變 [root@kube-node1 ~]# touch Dockerfile ##Dockerfile中所有的指令,必須是大寫的(例如: FROM, RUN, COPY等) #FROM 指定基礎鏡像,Dockerfile會對基礎鏡像進行編輯,生成新的鏡像 #MAINTAINER 指定創建鏡像者的信息 #RUN 指定制作命令, 一條RUN,就代表一條要在容器內執行的命令 #ENV 指定環境變量 #EXPOSE 開啟httpd服務要使用的端口,80和443 #WORKDIR 指定啟動容器后的,默認工作目錄 #ADD 指拷貝,Dockerfile目錄下的文件,拷貝到容器內(tar.gz,tar.bz2格式會自動解壓) #CMD 指定默認啟動命令,格式示例:#ls -la 則: CMD ["ls", "-l", "-a"] [root@kube-node1 bb]# vim Dockerfile FROM myos:latest MAINTAINER tarena RUN yum -y install httpd ENV LANG=C EXPOSE 80 443 WORKDIR /var/www/html ADD index.html /var/www/html/index.html CMD ["/usr/sbin/httpd","-DFOREGROUND"]
############ 創建apache的默認訪問頁面,在kube-node1上操作 ############## [root@kube-node1 bb]# echo "hello world" > index.html
創建服務鏡像:docker build -t myos:httpd
########## 使用Dockerfile文件,創建新的鏡像,在kube-node1上操作 ########## ##build 創建新的鏡像;-t 指定新鏡像的名字和標簽;. 指定Dockerfile文件所在的目錄 [root@kube-node1 bb]# docker build -t myos:httpd . Sending build context to Docker daemon 3.072 kB Step 1 : FROM myos:latest ---> 10a665c54e58 Step 2 : RUN yum -y install httpd ---> Running in b3226773e826 .......
運行容器驗證服務
dockeer run -itd myos:httpd
docker inspect 容器id
curl?http://ip.xx.xx.xx/?驗證結果
############# 驗證查看鏡像,在kube-node1上操作 ############# ##查看鏡像,myos:httpd 鏡像創建成功 [root@kube-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE myos httpd 019f5b48a5a0 About a minute ago 372.4 MB ...... ##使用myos:httpd 鏡像,創建一個容器 [root@kube-node1 ~]# docker run -itd myos:httpd 800b21aa9736bd68a521e7d5667835710b24829a136c5a0baa3e24cc319d3b70 ##查看正在使用的容器 [root@kube-node1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 800b21aa9736 myos:httpd "/usr/sbin/httpd -DFO" About a minute ago Up About a minute 80/tcp, 443/tcp reverent_thompson ##查看容器的詳細信息 [root@kube-node1 ~]# docker inspect 800b21aa9736 ........ ........ ########## ENV中, PATH 指定可執行文件的搜索路徑,為命令的默認查找路徑 ########### ############# 如果沒有指定PATH,則執行所有命令,都需要指定絕對路徑 ########### "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "LANG=C" ], ############# Cmd 默認的啟動命令,即:啟動容器時,默認的啟動命令 ############# "Cmd": [ "/bin/sh", "-c", "#(nop) ", "CMD [\"/usr/sbin/httpd\" \"-DFOREGROUND\"]" ], ........ ........ "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "b0cf7b16b65e272fa685ac975bce1f13647379beb8e22191d6623e30817829bc", "EndpointID": "f010d043874446d28892fa52903165f7370cccbc7cf449d325ad07c1c58fe6c4", ################## 容器的網關和IP地址 ######################### "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02" ........ ........
####### 根據容器的IP地址,訪問容器內的httpd服務,在kube-node1上操作 ######## ##訪問容器內的apache服務 [root@kube-node1 ~]# curl http://172.17.0.2 hello world
九、私有倉庫
安裝部署私有倉庫
安裝私有倉庫(服務端)?yum install docker-distribution
啟動私有倉庫,并設置開機自啟動 :systemctl start docker-distribution?systemctl enable docker-distribution
私有倉庫的配置:
倉庫配置文件 /etc/docker-distribution/registry/config.yml
數據存儲路徑:/var/lib/registry
默認端口號:5000
我們可以通過 curl 命令訪問倉庫 curl?http://倉庫ip:5000/v2
docker主機修改配置文件?/etc/sysconfig/docker
允許非加密方式訪問倉庫?INSECURE_REGISTRY='--insecure-registry 倉庫IP:5000'
docker倉庫地址?ADD_REGISTRY='--add-registry 倉庫IP:5000'
重啟docker 服務?systemctl restart docker
十、外部存儲卷
卷的用途
Docker容器不保持任何數據,重要數據請使用外部卷存儲(數據持久化),容器可以掛在真實機目錄或共享存儲為卷
首先,Docker?是一個進程(隨著機器的啟動而運行,隨著機器的停止而消失);
然后,所以Docker容器內不適合存放任何的數據,容易丟失;
最后,需要對Docker進行數據解耦(把Docker應用和數據存放進行分離);
將真實機目錄掛載到容器中提供持久化存儲,目錄不存在就自動創建,目錄存在就直接覆蓋掉,多個容器可以映射同一個目錄,來達到數據共享的目的
啟動容器時,使用 -v 參數映射卷?docker run -it -v 真實目錄: 容器內目錄 docker.io/centos: latest
有多臺 docker 主機的情況下,我們也可以使用共享存儲,來作為docker的卷服務,可以實現多主機之間多容器的共享卷服務
十一,發布 docker 服務
怎么訪問 docker 服務
默認容器可以訪問宿主機,但外部網絡的主機不可以訪問容器內的資源,解決這個問題的最佳方法是端口綁定,容器可以與宿主機的端口進行綁定,從而把宿主機變成對應的服務。宿主機和容器內部的服務端口綁定以后,用戶在訪問宿主機的服務端口時,就是在訪問容器內部的服務
我們使用?-p參數把容器端口和宿主機端口綁定?-p 宿主機端口: 容器端口
例如:把宿主機變成?httpd
docker run -itd -p 80:80 docker.io/myos:httpd
例如:把宿主機變成nginx
docker run -itd -p 80:80 docker.io/nginx:latest
Podman(podmanager):
是一個功能齊全的容器引擎,它是一個簡單的無需守護的用來管理鏡像、容器的工具。Podman提供了一個與Docker CLI兼容的操作方式,簡單地說:alias docker=podman。大多數Podman命令都可以普通用戶運行,而無需其他額外的權限。
圖片
指的是針對應用所需的運行環境資源(依賴庫/目錄/網絡/用戶……等)進行整體封裝的技術。封裝好的鏡像相比虛擬機的粒度要更細,可移植性強。每個容器采用沙箱機制,相互隔離。
傳統虛擬化與容器技術對比:
圖片
倉庫=》鏡像=》容器?的關系:
倉庫:用來提供/存放鏡像,有官方倉庫(比如紅帽的registry.redhat.io、刀客的docker.io),或自建私有倉庫。
鏡像:針對某個虛擬機或某個應用封裝的獨立環境,作為容器的模板。
容器:基于某個鏡像啟動的在內存中運行的實例。
圖片
# yum module install -y container-tools //安裝容器工具及其模塊配置 # yum install -y podman-docker //安裝docker兼容包(可選)
1)設置默認的倉庫地址(全局配置)
可以使用官方倉庫(比如registry.access.redhat.com)、第三方倉庫(比如docker.io),或者私有倉庫(比如registry.lab.example.com)。
# vim /etc/containers/registries.conf [registries.search] registries = ['registry.lab.example.com'] //設置搜索鏡像的默認倉庫地址 .. .. [registries.insecure] registries = ['registry.lab.example.com'] //允許訪問不安全的倉庫(比如HTTPS證書無效或過期等情況) .. ..
2)登錄倉庫(如果需要的話,比如push上傳鏡像時)
# podman login registry.lab.example.com Username: admin Password: *********** Login Succeeded!
3)搜索倉庫中的鏡像(比如nginx)
# podman search nginx INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED example.com registry.lab.example.com/library/nginx
1)下載鏡像到本地
# podman pull registry.lab.example.com/library/nginx .. .. //容器存儲默認工作目錄 /var/lib/containers/
2)查看鏡像
# podman images //列出本地鏡像 REPOSITORY TAG IMAGE ID CREATED SIZE registry.lab.example.com/nginx latest 4bb46517cac3 3 months ago 137 MB # podman image inspect 4bb4 //查看xxxx鏡像的詳細配置信息 .. ..
3)導出/備份鏡像
# podman save nginx > /root/nginx.tar
4)導入鏡像
# podman load -i /root/nginx.tar nginx-new:latest
5)刪除鏡像
# podman rmi xxxx //刪除ID為xxxx的鏡像 # podman rmi -a //刪除所有鏡像
1)在后臺啟動一個容器(-d 后臺運行)
# podman run -d registry.lab.example.com/library/nginx 80b22e7bd4d789773223f5afc85808ea472e82ec72f162903cd658ed6d98091c # podman ps //列出啟用中的容器(結合-a選項可以列出所有) .. .. # podman container inspect 4bb4 //查看xxxx容器的詳細信息 .. ..
2)新啟動一個容器并執行其中的命令“cat /etc/os-release”,然后刪除此容器
# podman run --rm registry.lab.example.com/library/nginx cat /etc/os-release PRETTY_NAME="Debian GNU/Linux 10 (buster)" NAME="Debian GNU/Linux" .. ..
3)啟動一個容器,并進入容器內的/bin/bash命令行環境(-i 允許交互,-t 開啟終端)
# podman run -it registry.lab.example.com/library/nginx /bin/bash root@840b592a6d3f:/# nginx -v //檢查nginx版本 nginx version: nginx/1.19.2 root@840b592a6d3f:/# ls /usr/share/nginx/html/ //檢查網頁目錄 50x.html index.html root@840b592a6d3f:/# exit //退出容器 exit #
4)在后臺啟動一個nginx容器,添加端口映射(-p 本地端口:容器端口)
[root@red ~]# podman run -d -p 8000:80 nginx 2b9ef8c0864149e2cf7860e903e36ba9deaa1717863f172b2bf2e5c5f3f6600c [root@red ~]# podman ps //列出活動中的容器 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2b9ef8c08641 registry.lab.example.com/library/nginx:latest nginx -g daemon o... 2 minutes ago Up 2 minutes ago 0.0.0.0:8000->80/tcp ecstatic_maxwell .. .. [root@red ~]# curl http://127.0.0.1:8000 //通過主機端口訪問容器中的web站點
5)在后臺啟動一個nginx容器,將主機的/opt/webroot映射為此nginx容器的web目錄(-v 本地目錄:容器內目錄)【持久存儲】
# mkdir /opt/webroot //準備網頁目錄 # echo "Podman Test" > /opt/webroot/index.html //準備默認測試網頁 # podman run -d -p 8001:80 -v /opt/webroot:/usr/share/nginx/html nginx ba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca # curl http://127.0.0.1:8001 //測試結果 Podman Test
1)連接到ID值以ba64開頭的(或者以-l表示最近一個容器)容器的命令行
[root@red ~]# podman exec -it ba64 bash root@ba64a15abdce:/# service nginx status [ ok ] nginx is running. root@ba64a15abdce:/# exit exit [root@red ~]#
2)檢查容器的IP地址
[root@red ~]# podman inspect ba64 | grep IPAddress .. .. "SecondaryIPAddresses": null, "IPAddress": "10.88.0.6", .. ..
3)從主機向ID值為ba64的(或者以-l表示最近一個容器)容器傳輸文件
[root@red ~]# echo AAAA > /root/a.html //建立測試網頁 [root@red ~]# podman cp /root/a.html ba64:/usr/share/nginx/html/a.html //復制文件到容器 [root@red ~]# curl http://127.0.0.1:8001/a.html //確認結果 AAAA
4)通過映射端口訪問容器中的Web服務
[root@red ~]# curl http://localhost:8001/ //瀏覽8001端口訪問目標容器首頁 Podman Test [root@red ~]# curl http://localhost:8001/a.html //瀏覽指定頁面 AAAA
1)關閉/殺死ID值為ba64的容器
[root@red ~]# podman stop ba64 //若要殺容器改用kill ba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca [root@red ~]# podman ps -a | grep ba64 //檢查容器狀態 ba64a15abdce registry.lab.example.com/library/nginx:latest nginx -g daemon o... 47 minutes ago Exited (0) 25 seconds ago 0.0.0.0:8001->80/tcp dreamy_swirles
2)重新啟動被關閉的ID值為ba64的容器
[root@red ~]# podman start ba64 //啟用已關閉的xx容器 ba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca [root@red ~]# podman ps -a | grep ba64 //檢查容器狀態 ba64a15abdce registry.lab.example.com/library/nginx:latest nginx -g daemon o... 48 minutes ago Up 2 seconds ago 0.0.0.0:8001->80/tcp dreamy_swirles
3)強制刪除ID值為ba64的容器
[root@red ~]# podman rm -f ba64 //刪除已關閉的xx容器(如果不加-f,則需要先stop此容器) ba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca [root@red ~]# podman ps -a | grep ba64 //檢查刪除結果(無輸出) [root@red ~]#
1)啟動一個容器,命名為myweb
[root@red ~]# podman run --name myweb -d -p 80:80 -v /opt/webroot:/usr/share/nginx/html nginx 52e6996bef86c501731115216c84a2f48d1a03f8c1a2cad70d27e281bd642b18
2)為名稱為myweb的容器創建對應的systemd服務配置
[root@red ~]# cd /etc/systemd/system/ //進入服務配置目錄 [root@red system]# podman generate systemd -n myweb --files /etc/systemd/system/container-myweb.service
3)更新systemd服務配置
[root@red system]# systemctl daemon-reload
4)配置congtainer-myweb服務開機自啟
[root@red system]# systemctl enable container-myweb Created symlink /etc/systemd/system/multi-user.target.wants/container-myweb.service → /etc/systemd/system/container-myweb.service.
5)關閉當前運行的容器
[root@red system]# podman stop 52e6 52e6996bef86c501731115216c84a2f48d1a03f8c1a2cad70d27e281bd642b18
6)重啟主機后,檢查是否可以訪問此web
[root@red system]# reboot .. .. [root@server1 ~]# curl http://172.25.0.26/ Podman Test
通過rootless無根模式,非特權用戶也可以很方便的運行容器(允許開啟1024以上端口),以提高服務管理的安全性。
!!! 確認非特權用戶的起始可用端口(需要時可更改)
# cat /proc/sys/net/ipv4/ip_unprivileged_port_start 1024
使用systemctl --user會話時,注意要直接以普通用戶SSH或console控制臺登錄,不要使用su或sudo的方式執行。
1)配置倉庫
可參考man containers-registries.conf手冊,
如果已經在/etc/containers/registries.conf 文件全局設置過,這里可以不做。
[zaniu@red ~]$ mkdir -p ~/.config/containers [zaniu@red ~]$ vim ~/.config/containers/registries.conf unqualified-search-registries = ['registry.lab.example.com'] [[registry]] location = "registry.lab.example.com" insecure = true //允許訪問不安全的倉庫(全局配置中也需要添加倉庫地址) blocked = false
2)下載(或導入)鏡像
[zaniu@red ~]$ podman login registry.lab.example.com //登錄倉庫(如果倉庫要求的話) Username: admin Password: Login Succeeded! [zaniu@red ~]$ podman pull registry.lab.example.com/library/nginx //下載鏡像到本地 .. .. //用戶容器存儲默認工作目錄 ~/.local/share/containers/ [zaniu@red ~]$ podman images //檢查本地鏡像 REPOSITORY TAG IMAGE ID CREATED SIZE registry.lab.example.com/library/nginx latest 4bb46517cac3 3 months ago 137 MB
2)啟動一個名為xxnginx的容器(如果SELinux要求啟用的話,可以通過:Z傳遞安全標簽)
[zaniu@red ~]$ mkdir /home/zaniu/html [zaniu@red ~]$ echo zaniu > /home/zaniu//html/index.html [zaniu@red ~]$ podman run --name xxnginx -d -p 8080:80 -v /home/zaniu/html:/usr/share/nginx/html:Z nginx 8fa1bc2ccd14ddc57e187ffe8e0035b6bfb1c3189460b3470b3935365f5d9a85 [zaniu@red ~]$ curl http://127.0.0.1:8080 zaniu
3)創建container-xxnginx服務配置
[zaniu@red ~]$ mkdir -p ~/.config/systemd/user //創建用戶服務配置目錄 [zaniu@red ~]$ cd ~/.config/systemd/user //進入用戶服務配置目錄 [zaniu@red user]$ podman generate systemd --name xxnginx --files //生成container-xxnginx服務配置 /home/zaniu/.config/systemd/user/container-xxnginx.service
4)更新用戶服務配置,設置開機自啟動
[zaniu@red user]$ systemctl --user daemon-reload //更新用戶服務配置 [zaniu@red user]$ systemctl --user enable container-xxnginx.service //配置自啟動 Created symlink /home/zaniu/.config/systemd/user/multi-user.target.wants/container-xxnginx.service → /home/zaniu/.config/systemd/user/container-xxnginx.service. [zaniu@red user]$ loginctl enable-linger //允許為未登錄的用戶啟動/保持后臺服務 //如果linger方式無效,也可以通過用戶計劃任務實現開機自啟動 [zhsan@red user]$ crontab -e @reboot systemctl --user start container-xxnginx.service
5)測試用戶服務控制
【與云原生的故事】有獎征文火熱進行中:https://bbs.huaweicloud.com/blogs/345260
Docker 云原生
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。