文章目錄
1.docker的介紹
docker 是管理容器的引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後發佈到任何流行的Linux機器或Windows 機器上,爲應用打包、部署平臺、而非單純虛擬化。內核共享宿主機
一個完整的Docker有以下幾個部分組成:
DockerClient客戶端
Docker Daemon守護進程
Docker Image鏡像
DockerContainer容器
傳統 VM: Application->Filesystem->GuestOS->VirtualizationStation->HostOS->Hardware
容器: Application->Filesystem->HostOS->Hardware
對開發:buildonce,runanywhere
對運維:configureonce,runanything
傳統虛擬化(虛擬機)與容器技術對比
docker 容器: 共享宿主機 os;鏡像小;幾乎無性能損耗;輕量,靈活遷移;安全隔離;快 速,秒級;單機支持上千容器
虛擬機: 宿主機上運行虛擬機 OS;鏡像大(GB) ;操作系統額外的 CPU、內存消耗;笨重、 與虛擬化技術耦合度高;完全隔離;慢,分鐘級;一般幾十個
2.Docker的安裝
1.配置 rhel7.5 的 yum 源,獲取 docker 安裝包
yum install -y docker-ce-18.09.6-3.el7.x86_64.rpm
docker-ce-cli-18.09.6-3.el7.x86_64.rpm
containerd.io-1.2.5-3.1.el7.x86_64.rpm
container-selinux-2.21-1.el7.noarch.rpm
2.啓動 docker
systemctl start docker
systemctl enable docker
設置開機啓動
3.導入鏡像並運行
docker 的數據都放在/var/lib/docker 下
導入2048遊戲
docker load -I game2048.tar
導入遊戲2048的鏡像
docker images
查看系統存在的鏡像
docker run -d --name game1 -p 80:80 game2048
後臺運行容器 (-d後臺運行,-p端口映射)
docker ps
查看當前運行的容器
docker ps -a
查看所有的容器
docker info
查看 docker 信息
vim /etc/sysctl.d/docker.conf
解決docker信息中的警告
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
sysctl --system
使生效
docker rm -f vm1
強制刪除正在運行的容器
導入ubuntu
docker load -I ubuntu.tar
導入遊戲2048的鏡像
docker run -it --name vm1 ubuntu
交互式運行容器 (-it交互式運行)
交互式的結束:
ctrl+pq 不停止容器,後臺運行
ctrl+d 直接結束容器,釋放內存
注意:docker使用copy-on-write機制,類似快照,鏡像層是隻讀的
3.鏡像構建
3.1 docker commit(不推薦)
docker load -I busybox.tar
導入busybox的鏡像,busybox,最基礎的根文件系統, 適合從零開始構建鏡像
docker run -it --name vm1 busybox
運行容器
/#echo hello world > testfile 建立文件
這時候如果 ctrl+d 會退出容器並關閉,ctrl+p+q 會退出但是不關閉
docker attach vm1
重新連接到容器
docker commit vm1 test:v1
提交更改過的容器
docker images test
==注意:dockercommit 無法看到我們在 shell 中做了什麼操作,鏡像無法審計,有安全隱患,不推薦使用 ==
3.2 Dockerfile 方式( 推薦!!)
mkdir/root/docker
新建一個目錄來放 dockerfile,裏面不要放其他文件, 不然 docker 引擎會提交所有數據
vim /root/docker/dockerfile
FROM busybox ##指定以哪個鏡像爲基礎
RUN echo testfile>file1##要做的事情
RUN echo testfile>file2
cd /root/docker
docker build -t test:v2.
. 表示提交當前目錄中的內容
docker history test:v2
可以看到構建過程
注意:要使用緩存特性,前面的內容都不能更改(一個空格也不行),只 能新增
4.dockerfile 詳解
4.1 COPY(拷貝本機文件到容器):
vim dockerfile
FROM busybox
COPY testfile /tmp
echo hello world > testfile
建立本地文件,testfile 文件必須放在 dockerfile 的目錄中
docker build -t test:v1 .
構建鏡像
docker run -it --name vm1 test:v1
運行容器
4.2 ADD(拷貝的同時解壓文件):
vim dockerfile
FROM busybox
ADD nginx-1.17.0.tar.gz /tmp
docker build -t test:v2 .
構建鏡像
docker run -it --name vm1 test:v1
運行容器
4.3VOLUME(數據卷)
vim dockerfile
FROM busybox
VOLUME ["/data"] ##在容器啓動時會自動新建這個目錄
docker build -t test:v3 .
構建鏡像
docker run -it --name vm1 test:v3
運行容器
docker inspect vm1
##查看 vm1具體信息 “Source”:
"/var/lib/docker/volumes/434ef33ab2e3b117435bb062f3adbd21d8649d6ec39be7ea407d804f0b 0745cb/_data"
#這個是數據卷掛載,在容器運行時,會在宿主機上生成此目錄並和容器 的/data 目錄關聯(其實兩個目錄是同步的)
cd /var/lib/docker/volumes/434ef33ab2e3b117435bb062f3adbd21d8649d6ec39be7ea407d804f0b 0745cb/_data
touch file1
docker attach vm1
可以在/data看到在宿主機上新建的文件,容器裏也可以看到,在容器裏刪除這些文 件,宿主機上也就刪除了
注意中間容器 的退出爲ctrl+p+q退出不關閉。
也可以指定容器中數據卷的掛載
docker run -it --name vm2 -v /opt/data:/data test:v3
##冒號前是宿主機的 目錄(不存在會自動新建),冒號後是容器對應的目錄
4.4 WORKDIR置在鏡像中的工作目錄
WORKDIR爲 ADDRUNCOPY 等命令設置在鏡像中的工作目錄,不存在會新建
CMD 和 ENTRYPOINT 都是用於設置容器啓動後執行的命令,但是 CMD 會被 dockerrun 後 面的命令行覆蓋,而 ENTRYPOINT 一定會被執行
docker run 後面的參數可以傳遞給 ENTRYPOINT 指令當作參數。Dockerfile 中只能指定一個 ENTRYPOINT,如果有多個,只有最後一個生效。
官方推薦使用 exec 格式
1.dockerfile的shell 格式+ENTRYPOINT
shell 格式
vim dockerfile
FROM busybox
ENV name world ##定義表量 name,值爲 world
ENTRYPOINT echo "hello,$name" #使用變量
docker build -t test:v5 .
docker run --rm test:v5
##–rm 表示容器是一次性的,運行完就刪除
2.dockerfile的exec 格式+ENTRYPOINT
exec 格式
vim dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo","hello,$name"]##變量無法被解析
ENTRYPOINT["/bin/sh","-c","echohello,$name"]##變量可以被被成功解析
docker build -t test:v7 .
docker run --rm test:v7
–rm 表示容器是一次性的,運行完就刪除
3.dockerfile的exec 格式+CMD
vim dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
**docker build -t test:v8 .
docker run --rm test:v8
##當 docker run 命令行裏沒有指定命令時,CMD 會執行,有的話 CMD 命令就 會被覆蓋
docker run --rm test:v8 linux
**加上 linux參數,會覆蓋掉 world
5.鏡像優化
鏡像優化(選擇最精簡的基礎鏡像;減少鏡像層數;清理鏡像構建的中間產物;注意優化 網絡請求;儘量用構建緩存;使用多階段構建鏡像)
5.1 構建 nginx 鏡像
實例:構建 nginx 鏡像
docker load -i rhel7.tar
vim Dockerfile
FROM rhel7
EXPOSE 80 ##暴露的端口
MAINTAINER [email protected]
COPY source.repo /etc/yum.repos.d/ ##source.repo需要在同級目錄
RUN rpmdb --rebuilddb ##在 yum 之前重新構建 rpm 數據庫
RUN yum install -y gcc make pcre-devel zlib-devel
ADD nginx-1.16.0.tar.gz/mnt
WORKDIR /mnt/nginx-1.16.0
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
ENTRYPOINT ["/usr/local/nginx/sbin/nginx" , "-g" , "daemonoff;"]
docker build -t nginx:v1 .
5.2 鏡像優化1——清理鏡像構建的中間產物
在使用 yum 安裝軟件包時會產生緩存,在/var/cache/yum 中
可以清理 yum 緩存和編譯後的目錄
vim Dockerfile
FROM rhel7
EXPOSE 80
MAINTAINER [email protected]
COPY source.repo /etc/yum.repos.d/
RUN rpmdb --rebuilddb
RUN yum install -y gcc make pcre-devel zlib-devel && yum clean all
ADD nginx-1.16.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.16.0
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
RUN rm -fr /mnt/nginx-1.16.0
ENTRYPOINT ["/usr/local/nginx/sbin/nginx" , "-g" , "daemonoff;"]
docker build -t nginx:v2 .
5.2 鏡像優化2——減少鏡像層數
vim Dockerfile
FROM rhel7
EXPOSE 80
MAINTAINER [email protected]
COPY source.repo /etc/yum.repos.d/
ADD nginx-1.16.0.tar.gz /mnt
WORKDIR /mnt/nginx-1.16.0
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && yum clean all &&./configure--prefix=/usr/local/nginx&&make&&makeinstall&&rm-fr/mnt/nginx-1.16.0
ENTRYPOINT ["/usr/local/nginx/sbin/nginx" , "-g" , "daemonoff;"]
docker build -t nginx:v3 .
5.3 鏡像優化3——多階段構建鏡像
多階段構建鏡像,可以最大化縮減鏡像大小。
在構建 nginx 鏡像時,最終只需要的是/usr/local/nginx 的二進制程序,其他過程都可以不要 #那麼我們可以把構建過程在一個鏡像中完成,二進制程序放在一個新的鏡像中,這樣新的鏡像就很小了
vim Dockerfile
FROM rhel7 as build ##作爲構建過程的鏡像
EXPOSE 80
MAINTAINER [email protected]
COPY source.repo /etc/yum.repos.d/
ADD nginx-1.16.0.tar.gz/mnt
WORKDIR /mnt/nginx-1.16.0
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && yum clean all &&./configure--prefix=/usr/local/nginx&&make&&makeinstall&&rm-fr/mnt/nginx-1.16.0
FROM rhel7
EXPOSE 80
MAINTAINER [email protected]
VOLUME ["/usr/local/nginx/html"]##使用容器時可以在宿主機對容器內容進行發佈
COPY --from=build/usr/local/nginx/usr/local/nginx ##拷貝 nginx 程序目錄
ENTRYPOINT ["/usr/local/nginx/sbin/nginx","-g","daemonoff;"]
docker build -t nginx:v4 .
5.4 鏡像優化4——使用更加精簡的基礎鏡像
docker load -I nginx.tar
##導入 nginx 鏡像
docker load -I distroless.tar
##導入 base 鏡像
編寫 dockerfile
mkdir distroless
vim Dockerfile
FROM nginx as base
#https://en.wikipedia.org/wiki/List_of_tz_database_time_zones ARG
Asia/Shanghai #修改時區
RUN mkdir -p /opt/var/cache/nginx &&\
cp -a --parents /usr/lib/nginx /opt &&\
cp -a --parents/usr/share/nginx /opt &&\
cp -a --parents/var/log/nginx /opt &&\
cp -aL --parents/var/run /opt &&\
cp -a --parents/etc/nginx /opt &&\
cp -a --parents/etc/passwd/opt &&\
cp -a --parents/etc/group /opt &&\
cp -a --parents/usr/sbin/nginx /opt &&\
cp -a --parents/usr/sbin/nginx-debug /opt &&\
cp -a --parents/lib/x86_64-linux-gnu/libpcre.so.* /op t&&\
cp -a --parents/lib/x86_64-linux-gnu/libz.so.* /opt &&\
cp -a --parents/lib/x86_64-linux-gnu/libc.so.* /opt &&\
cp -a --parents/lib/x86_64-linux-gnu/libdl.so.* /opt &&\
cp -a --parents/lib/x86_64-linux-gnu/libpthread.so.* /opt &&\
cp -a --parents/lib/x86_64-linux-gnu/libcrypt.so.* /opt &&\
cp -a --parents/usr/lib/x86_64-linux-gnu/libssl.so.* /opt &&\
cp -a --parents/usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt &&\
cp/usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime
FROM gcr.io/distroless/base
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx","-g","daemonoff;"]
docker build -t nginx:v5 .
docker run -d --name nginx ngin:5
docker rm -f nginx
docker build -t nginx:v5 .
docker run -d -p 80:80 --name nginx ngin:5