一、Docker 原理
docker是什么?
Docker 是完整的一套容器管理系統,所以想要搞懂 Docker 的概念,我們必須先從容器開始說
起。什么是容器?
- 容器是用來裝東西的(類似運行的啟動盤),linux 里面的容器是用來裝應用的;
- 容器就是將軟件打包成標準化單元,以用于開發(fā)、交付和部署;
- 容器技術已經成為應用程序封裝和交付的核心技術;
容器原理
容器技術的核心,由以下幾個內核技術組成:
- Cgroups (Control Groups) — 資源管理
- SELinux — 安全 (是針對于文件系統,文件的管理措施)
- NameSpace — 命名空間是指可以對系統資源空間進行分割隔離的技術,例如:創(chuàng)建一個虛擬機,在虛擬機里的所有操
作,都不會對真實機造成影響。命名空間分為六大類,可以從各個方面來對系統資源空間進行隔離;
Linux 的 NameSpace
- UTS:主機名命名空間,作用:分割主機名,即在容器內修改主機名,不會對宿主機的系統造成影響,實現主機名的隔離;
- NETWORK:網絡命名空間,作用:分割網絡,即容器內的網絡配置和宿主機相互之間不受干擾的;例如在真實機器上的網卡名為eth0,IP地址為192.168.1.10/24;而在容器內的網卡名可以為ens33,ip地址為10.10.10.10/24;
- MOUNT:掛載命名空間,作用:隔離文件系統,在容器內掛載的光盤或nfs共享目錄,宿主機是無法看到里面的內
容的;例如:在linux系統上,創(chuàng)建一個虛擬機,在真機的/var/lib/ftp中掛載了一個光盤文件,但是在虛擬機的/var/lib/ftp中是沒有光盤內容的,這就是MOUNT隔離; - USER:用戶命名空間,作用:隔離用戶,即容器內創(chuàng)建的用戶不能用于登錄宿主機,真機機里創(chuàng)建的用戶也不能
作用于容器; - PID:進程命名空間,作用:為了防止容器和宿主機中的進程沖突;例如:在真實機中,有一個服務: nfs,PID為2250;在容器內,也有一個服務: chrony,PID為2250;真實機中用戶,殺死(kill) PID號為2250的進程時,并不會對容器內的進程2250產生影響;而容器內的用戶,殺死(kill) PID號為2250的進程時,也并不會對真實機內的進程2250產生影響;
- IPC:信號向量命名空間,作用:通常和PID一起使用;用戶殺死一個進程時,實際上是向進程發(fā)送一個信號(IPC),進程接收到這個信號后會執(zhí)行對應的操作;
docker 的特性
docker 的優(yōu)缺點
- 優(yōu)點:相比于傳統的虛擬化技術,容器更加簡潔高效,傳統虛擬機需要給每個 VM 安裝操作系統,容器使用的共享公共庫和程序
- 缺點:容器的隔離性沒有虛擬機強共用Linux內核,安全性有先天缺陷.
docker 的特點
- docker 與傳統虛擬化的對比:虛擬化:例如:虛擬機的使用,每一個虛擬機都要安裝獨立的操作系統;將一臺服務器轉變?yōu)槎嗯_服務器的物理硬件的抽象。系統管理程序允許多個VM在單臺計算機上運行。每個VM包含操作系統,應用程序,必要的二進制文件和庫的完整副本-占用數十GB。VM也可能啟動緩慢。容器:不需要安裝獨立的操作系統,只有一個Docker進程,和宿主機共享操作系統;容器沒有操作系統,啟動容器就跟開啟一個進程一樣,簡單高效;是應用程序層的抽象,將代碼和依賴項打包在一起。多個容器可以在同一臺計算機上運行,?并與其他容器共享OS內核,每個容器在用戶空間中作為隔離的進程運行。容器占用的空間少于VM(容器映像的大小通常為幾十MB),可以處理更多的應用程序,并且需要的VM和操作系統更少。
- 運行區(qū)別( 容器的高效性):啟動虛擬機中的應用程序,需要先啟動虛擬機的操作系統,然后再啟動應用程序;啟動容器內的應用程序,直接啟動應用程序即可;
二、docker 安裝部署
docker安裝
安裝條件
- 需要64位操作系統,至少 RHEL6.5 以上的版本,強烈推薦 RHEL7
- docker安裝時,內核要求在3.0以上,RHEL7的內核默認在3.0以上,不滿足可以單獨升級系統內核。
查看linux系統的內核版本,【uname -r】也可以
- 關閉防火墻 (不是必須):firewalld【RHEL7使用】,Iptables【RHEL6使用】,Docker安裝時,會自動的接管防火墻,并向防火墻里添加配置,如果防火墻存在,會產生沖突。
源配置
- 配置 yum 源
- 在物理機的 http 目錄下創(chuàng)建文件夾 extras: mkdir /var/www/html/extras
- 把光盤掛到這個目錄下 : mount -t iso9660 -o ro,loop RHEL70OSP-extras.iso /var/www/html/extras
docker安裝
- 卸載防火墻 yum remove -y firewalld-*
- 安裝軟件包 yum install docker
- 開啟路由轉發(fā) /etc/sysctl.conf net.ipv4.ip_forward=1 使用sysctl -p讓配置立刻生效(否則需要重新虛擬機)docker是通過虛擬交互機來進行通訊的,需要開啟路由轉發(fā)的功能。
- 軟件的 BUG :iptables -nL FORWARD 版本 大于 1.12 時會設置 FORWARD 的默認規(guī)則,被設置為 DROP,對于有些docker的版本中,FORWARD鏈的規(guī)則被設置成了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(寫時復制)的技術,用戶可以使用一個鏡像文件創(chuàng)建多個容器,互不干擾;
- 鏡像采用分層技術:用戶可以根據自己的需求來制作鏡像,例如:在鏡像的第一層定義應用程序的變量,在鏡像的第二層修改配置文件,在鏡像的第三層進行應用軟件的部署;分層做好鏡像后,用戶使用鏡像啟動容器時,可以選擇根據鏡像的哪一層來啟動,類似快照還原;
容器使用鏡像啟動
鏡像是怎么來的?
鏡像可以從官方鏡像倉庫下載,也可以自己制作
- 官方鏡像倉庫:https://hub.docker.com
- 查看本機鏡像 docker images
- #REPOSITORY 鏡像名稱
- #TAG 鏡像標簽
- #IMAGE ID 鏡像ID號
- #CREATED 鏡像創(chuàng)建時間
- #SIZE 鏡像大小
獲取鏡像
查找鏡像:docker search 關鍵字 docker search jdk
- #INDEX 索引名稱,即網站域名
- #NAME 鏡像的名稱
- #DESCRIPTION 鏡像的描述信息
- #STARS 鏡像被下載的次數
- #OFFICIAL 是否是docker官方開發(fā)的
- #AUTOMATED 是否自動構建鏡像
下載鏡像docker pull 鏡像名稱:標簽 :docker pull docker.io/busybox
鏡像的備份與恢復
備份鏡像 (導出鏡像):docker save 鏡像名稱:鏡像標簽 -o 備份文件夾(tar格式)
- 鏡像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 備份文件名稱
docker load -i busybox.tar
四、第一個容器
運行容器
docker run 命令
docker run -參數 鏡像名稱:鏡像標簽 啟動命令
- 鏡像名稱:鏡像標簽這種形式,可以指定唯一的鏡像,防止鏡像名相同,內容不同的情況,latest為默認標簽,創(chuàng)建鏡像時,不指定標簽,則為此默認標簽
+run = 創(chuàng)建 + 啟動 +進入,docker run 命令: 運行過程中,會先根據鏡像來創(chuàng)建容器,然后會啟動容器,最后進入容器 - 幫助文檔:查看 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 容器idattach 以上帝進程的身份,進入容器內部,使用attach進入容器,是上帝進程的身份進入容器的,當執(zhí)行exit退出容器時,會結束整個容器,查看進程樹,systemd就是上帝進程,即:系統服務的最初進程,所有的進程都是在上帝進程下創(chuàng)建的;當systemd進程被結束時,整個系統也就會崩潰通常用于在測試時,查看報錯信息;
- 連接容器,啟動新進程 docker exec -it 容器id 命令在對容器的使用過程中,都是使用exec,新開一個進程的方式進入容器,進行編輯的;而attach 往往應用于調試,終端輸出的情況;
七,自定義鏡像
commit 自定義鏡像
自定義鏡像原理 :鏡像采用分層設計:1,創(chuàng)建讀寫層 2,修改配置 3,重新打包
使用鏡像啟動容器,在該容器基礎上修改,另存為一個新鏡像
- docker run -it docker.io/centos:latest /bin/bash
- 配置 yum,安裝軟件,系統配置
- docker commit 容器id 新鏡像名稱: 新鏡像標簽
############## 創(chuàng)建一個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:制作鏡像時執(zhí)行的命令,可以有多個
- ADD:復制文件到鏡像,自動解壓 (文件類型為: tar.gz 或 tar.bz2)
- COPY:復制文件到鏡像,不解壓
- MAINTAINER:鏡像創(chuàng)建者信息
- EXPOSE:開放的端口
- ENV:設置變量
- WORKDIR:定義容器默認工作目錄
- CMD: 容器啟動時執(zhí)行的命令,僅可以有一條CMD.
- ENTRYPOINT:類似CMD指令的功能,用于為容器指定默認運行程序,從而使得容器像是一具單獨的可執(zhí)行程序
與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
創(chuàng)建鏡像
使用 Dockerfile 工作流程,根據Dockerfile生成新的鏡像,build創(chuàng)建新的鏡像;-t指定新鏡像的名字和標簽;. 指定Dockerfile文件所在的目錄
- mkdir build
- cd build
- 編寫 Dockerfile
########### 獲取制作鏡像的歷史命令,在kube-node1上操作 ##############
##利用myos鏡像,創(chuàng)建一個容器,可以查看之前制作鏡像的歷史命令
[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自動創(chuàng)建鏡像腳本,在kube-node1上操作 ##############
##創(chuàng)建一個目錄,名稱任意定義
[root@kube-node1 ~]# mkdir aa
##進入到aa目錄下
[root@kube-node1 ~]# cd aa/
##創(chuàng)建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,就代表一條要在容器內執(zhí)行的命令
#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 創(chuàng)建新的鏡像;-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創(chuàng)建成功
[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 創(chuàng)建服務鏡像
Dockerfile 創(chuàng)建 Apache 服務案例
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遠程執(zhí)行以下三條命令,f1和f2文件,最終都是創(chuàng)建在/root目錄下
#因為每次ssh連接都是代表不同的連接,無法保持上次連接時,命令的執(zhí)行狀態(tài)
[root@localhost ~]# ssh host1 touch f1
[root@localhost ~]# ssh host1 cd /tmp
[root@localhost ~]# ssh host1 touch f2
##### Dockerfile和ssh類似,所以要使用 WORKDIR容器默認工作目錄的指定 #####
在容器內安裝并啟動apache服務
###### 使用myos鏡像創(chuàng)建一個容器,在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的服務文件,獲取環(huán)境變量文件和服務啟動命令
[root@a670096c60ad /]# cat /lib/systemd/system/httpd.service
........
[Service]
........
#環(huán)境變量文件
EnvironmentFile=/etc/sysconfig/httpd
#啟動命令,$OPTIONS 此環(huán)境變量為空,可以不用寫
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
........
####從環(huán)境變量文件中,獲取環(huán)境變量
[root@a670096c60ad /]# vim /etc/sysconfig/httpd
......
LANG=C
####設置環(huán)境變量
[root@a670096c60ad /]# LANG=C
#啟動httpd服務,$OPTIONS 此環(huán)境變量為空,可以不用寫
#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
編寫http的Dockerfile文件
########## 制作Dockerfile自動創(chuàng)建鏡像腳本,在kube-node1上操作 ###########
##創(chuàng)建一個目錄,名稱任意定義
[root@kube-node1 ~]# mkdir bb
##進入到aa目錄下
[root@kube-node1 ~]# cd bb/
##創(chuàng)建Dockerfile文件,文件名不能改變
[root@kube-node1 ~]# touch Dockerfile
##Dockerfile中所有的指令,必須是大寫的(例如: FROM, RUN, COPY等)
#FROM 指定基礎鏡像,Dockerfile會對基礎鏡像進行編輯,生成新的鏡像
#MAINTAINER 指定創(chuàng)建鏡像者的信息
#RUN 指定制作命令, 一條RUN,就代表一條要在容器內執(zhí)行的命令
#ENV 指定環(huán)境變量
#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"]
############ 創(chuàng)建apache的默認訪問頁面,在kube-node1上操作 ##############
[root@kube-node1 bb]# echo "hello world" > index.html
運行容器
創(chuàng)建服務鏡像:docker build -t myos:httpd
########## 使用Dockerfile文件,創(chuàng)建新的鏡像,在kube-node1上操作 ##########
##build 創(chuàng)建新的鏡像;-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 鏡像創(chuàng)建成功
[root@kube-node1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myos httpd 019f5b48a5a0 About a minute ago 372.4 MB
......
##使用myos:httpd 鏡像,創(chuàng)建一個容器
[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 指定可執(zhí)行文件的搜索路徑,為命令的默認查找路徑 ###########
############# 如果沒有指定PATH,則執(zhí)行所有命令,都需要指定絕對路徑 ###########
"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
九、私有倉庫
安裝部署私有倉庫
創(chuàng)建私有倉庫
搭建私有倉庫
- 安裝私有倉庫(服務端) 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應用和數據存放進行分離);
主機卷的映射
將真實機目錄掛載到容器中提供持久化存儲,目錄不存在就自動創(chuàng)建,目錄存在就直接覆蓋掉,多個容器可以映射同一個目錄,來達到數據共享的目的
啟動容器時,使用 -v 參數映射卷 docker run -it -v 真實目錄: 容器內目錄 docker.io/centos: latest
多主機共享目錄
有多臺 docker 主機的情況下,我們也可以使用共享存儲,來作為docker的卷服務,可以實現多主機之間多容器的共享卷服務
十一,發(fā)布 docker 服務
怎么訪問 docker 服務
默認容器可以訪問宿主機,但外部網絡的主機不可以訪問容器內的資源,解決這個問題的最佳方法是端口綁定,容器可以與宿主機的端口進行綁定,從而把宿主機變成對應的服務。宿主機和容器內部的服務端口綁定以后,用戶在訪問宿主機的服務端口時,就是在訪問容器內部的服務
發(fā)布 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命令都可以普通用戶運行,而無需其他額外的權限。
圖片
容器(Container):
指的是針對應用所需的運行環(huán)境資源(依賴庫/目錄/網絡/用戶……等)進行整體封裝的技術。封裝好的鏡像相比虛擬機的粒度要更細,可移植性強。每個容器采用沙箱機制,相互隔離。
傳統虛擬化與容器技術對比:
圖片
倉庫=》鏡像=》容器 的關系:
- 倉庫:用來提供/存放鏡像,有官方倉庫(比如紅帽的registry.redhat.io、刀客的docker.io),或自建私有倉庫。
- 鏡像:針對某個虛擬機或某個應用封裝的獨立環(huán)境,作為容器的模板。
- 容器:基于某個鏡像啟動的在內存中運行的實例。
圖片
一、安裝環(huán)境
# 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. 啟動容器
- 1)在后臺啟動一個容器(-d 后臺運行)
# podman run -d registry.lab.example.com/library/nginx
80b22e7bd4d789773223f5afc85808ea472e82ec72f162903cd658ed6d98091c
# podman ps //列出啟用中的容器(結合-a選項可以列出所有)
.. ..
# podman container inspect 4bb4 //查看xxxx容器的詳細信息
.. ..
- 2)新啟動一個容器并執(zhí)行其中的命令“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命令行環(huán)境(-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站點
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
.. ..
- 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
2. 訪問運行中的容器
- 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
3. 關閉/殺死容器
- 1)關閉/殺死ID值為ba64的容器
[root@red ~]# podman stop ba64 //若要殺容器改用kill
ba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca
[root@red ~]# podman ps -a | grep ba64 //檢查容器狀態(tài)
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 //檢查容器狀態(tài)
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 ~]#
五、為容器設置systemd服務
- 1)啟動一個容器,命名為myweb
[root@red ~]# podman run --name myweb -d -p 80:80 -v /opt/webroot:/usr/share/nginx/html nginx
52e6996bef86c501731115216c84a2f48d1a03f8c1a2cad70d27e281bd642b18
- 2)為名稱為myweb的容器創(chuàng)建對應的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)環(huán)境
通過rootless無根模式,非特權用戶也可以很方便的運行容器(允許開啟1024以上端口),以提高服務管理的安全性。
!!! 確認非特權用戶的起始可用端口(需要時可更改)
# cat /proc/sys/net/ipv4/ip_unprivileged_port_start
1024
使用systemctl --user會話時,注意要直接以普通用戶SSH或console控制臺登錄,不要使用su或sudo的方式執(zhí)行。
- 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)創(chuàng)建container-xxnginx服務配置
[zaniu@red ~]$ mkdir -p ~/.config/systemd/user //創(chuàng)建用戶服務配置目錄
[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)測試用戶服務控制
[zaniu@red user]$ podman stop xxnginx //停止原來手動運行的容器
[zaniu@red user]$ systemctl --user start container-xxnginx.service //啟動容器服務
[zaniu@red user]$ systemctl --user status container-xxnginx.service //檢查容器狀態(tài)
[zaniu@red user]$ systemctl --user stop container-xxnginx.service //停止容器服務
6)重啟主機后,確認仍然可以訪問web
[root@red system]# reboot
.. ..
[root@server1 ~]# curl http://172.25.0.26:8080/