安裝、初步使用、鏡像、Dockerfile常用指令、通過Dockerfile檔案封裝nginx鏡像并優化
- 一、簡介
- 二、安裝
- 1.安裝配置
- 倉庫配有的安裝包
- 安裝
- 橋接
- 2.匯入馬里奧游戲
- 瀏覽器訪問172.25.15.1
- 3.洗掉
- 4.匯入2048游戲
- 三、鏡像
- 1.鏡像的分層結構
- 2.退出方式
- 3.分層
- 4.鏡像的構建
- 四、Dockerfile
- 1.常用指令
- 2.通過Dockerfile檔案封裝nginx鏡像
- 五、優化容器
- 1.第一種:簡單優化,減少鏡像層數
- 2.第二種:使用多階段構建鏡像
- 3.第三種:更換構建鏡像,選擇最精簡的基礎鏡像
一、簡介
- Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的鏡像中,然后發布到任何流行的 Linux或Windows 機器上,也可以實作虛擬化,容器是完全使用沙箱機制,相互之間不會有任何介面,
- 一個完整的Docker有以下幾個部分組成:
- DockerClient客戶端
- Docker Daemon守護行程
- Docker Image鏡像
- DockerContainer容器
二、安裝
1.安裝配置
[root@server1 ~]# vim /etc/yum.repos.d/westos.repo #配置軟體倉庫
[root@server1 ~]# cat /etc/yum.repos.d/westos.repo #查看配置
[root@server1 ~]# yum repolist #檢測倉庫
[root@server1 ~]# yum install -y docker-ce #安裝docker
[root@server1 ~]# systemctl enable --now docker #開啟docker服務,并設定為開機自啟
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@server1 ~]# docker info #查看
倉庫配有的安裝包

安裝





橋接
如果docker info 出現如下錯誤

[root@server1 ~]# sysctl -a | grep bridge-nf-call-iptables #查看是1的話不用修改,也不會出現上述問題
net.bridge.bridge-nf-call-iptables = 0 #修改為1
[root@server1 ~]# vim /etc/sysctl.d/docker.conf
[root@server1 ~]# cat /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
[root@server1 ~]# sysctl --system
[root@server1 ~]# docker info
Registry: https://index.docker.io/v1/


2.匯入馬里奧游戲
## 下載馬里奧游戲
[root@server1 ~]# lftp 172.25.15.250
lftp 172.25.15.250:~> cd pub/images/
lftp 172.25.15.250:/pub/images> get mario.tar
207414272 bytes transferred
lftp 172.25.15.250:/pub/images> exit
[root@server1 ~]# ls
mario.tar
[root@server1 ~]# docker load -i mario.tar #將游戲匯入容器
4aeeaca5ce76: Loading layer 197.2MB/197.2MB
708fd576a927: Loading layer 208.9kB/208.9kB
90222f49bc4c: Loading layer 4.608kB/4.608kB
5f70bf18a086: Loading layer 1.024kB/1.024kB
dbe97b1b7330: Loading layer 1.536kB/1.536kB
44e5704d49fb: Loading layer 9.912MB/9.912MB
Loaded image: mario:latest
[root@server1 ~]# docker run -d --name demo -p 80:8080 mario #運行
5ad30696ec3ce7c9efd33e5964f29333cb4dcd30e99c4d610f8195c2423f394c

瀏覽器訪問172.25.15.1

3.洗掉
[root@server1 ~]# docker ps -a #查看行程,所有的 (docker ps 正在運行的)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5ad30696ec3c mario "python3 -m http.ser…" 6 minutes ago Up 6 minutes 0.0.0.0:80->8080/tcp demo
[root@server1 ~]# docker rm -f demo #洗掉
demo
[root@server1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

4.匯入2048游戲
##下載2048游戲
[root@server1 ~]# lftp 172.25.15.250
lftp 172.25.15.250:~> cd pub/images/
cd ok, cwd=/pub/images
lftp 172.25.15.250:/pub/images> get game2048.tar
57176576 bytes transferred
lftp 172.25.15.250:/pub/images> exit
[root@server1 ~]# ls
game2048.tar mario.tar
[root@server1 ~]# docker load -i game2048.tar
011b303988d2: Loading layer 5.05MB/5.05MB
36e9226e74f8: Loading layer 51.46MB/51.46MB
192e9fad2abc: Loading layer 3.584kB/3.584kB
6d7504772167: Loading layer 4.608kB/4.608kB
88fca8ae768a: Loading layer 629.8kB/629.8kB
Loaded image: game2048:latest
[root@server1 ~]# docker run -d --name demo -p 80:80 game2048
6fb8beeaea6ae156afba03cca436e4b3dca01d023b7a92bb73979e41abbbc176
[root@server1 ~]#


三、鏡像
1.鏡像的分層結構
容器層以下所有鏡像層都是只讀的
docker從上往下依次查找檔案
容器層保存鏡像變化的部分,并不會對鏡像本身進行任何修改
一個鏡像最多127層
2.退出方式
- 編輯鏡像時
- ctrl+d #退出并洗掉
- ctrl+qp #直接退出,行程進入后臺
3.分層
[root@server1 ~]# cd /var/lib/docker/
[root@server1 docker]# docker pull busybox #
Using default tag: latest
latest: Pulling from library/busybox
Digest: sha256:0f354ec1728d9ff32edcd7d1b8bbdfc798277ad36120dc3dc683be44524c8b60
Status: Image is up to date for busybox:latest
docker.io/library/busybox:latest
[root@server1 docker]# docker run -it --name demo busybox #運行創建一個名字為demo的容器
/ # ls
bin dev etc home proc root sys tmp usr var
/ # touch file1
/ # touch file2
/ # touch file3
/ # touch file4
/ # touch file5
/ # ls
bin etc file2 file4 home root tmp var
dev file1 file3 file5 proc sys usr
/ #
[root@server1 docker]# docker ps #查看正在運行的
[root@server1 docker]# docker ps -a #所有
[root@server1 docker]# docker start demo #啟動容器demo
[root@server1 docker]# docker container attach demo #繼續編輯鏡像


[root@server1 docker]# docker commit demo demo:v1 #創建v1鏡像
[root@server1 docker]# docker commit history demo:v1 #查看V1鏡像
[root@server1 docker]# docker history busybox:latest
[root@server1 docker]# docker rmi demo:v1 #洗掉v1鏡像
[root@server1 docker]# docker images

有基礎的兩層,加上編輯的一層,共三層
洗掉v1

4.鏡像的構建
- docker commit 構建新鏡像三部曲
- 運行容器
- 修改容器
- 將容器保存為新的鏡像
- 缺點:
- 效率低、可重復性弱、容易出錯
- 使用者無法對鏡像進行審計,存在安全隱患
root@server1 ~]# mkdir docker
[root@server1 ~]# cd docker/
[root@server1 docker]# vim Dockerfile ##鏡像的構建
[root@server1 docker]# cat Dockerfile
FROM busybox ##指定base鏡像,如果本地不存在會從遠程倉庫下載
RUN touch file1
RUN mkdir westos
[root@server1 docker]# docker build -t demo:v1 . #創建v1
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM busybox
---> 69593048aa3a
Step 2/3 : RUN touch file1
---> Running in 645634f44648
Removing intermediate container 645634f44648
---> eec5bb41f5d2
Step 3/3 : RUN mkdir westos
---> Running in 9714250c45ee
Removing intermediate container 9714250c45ee
---> d3da9446a2c2
Successfully built d3da9446a2c2
Successfully tagged demo:v1
[root@server1 docker]# vim Dockerfile #再次撰寫好容器的操作
FROM demo:v1 ##指定base鏡像,如果本地不存在會從遠程倉庫下載
RUN touch file2
RUN mkdir redhat
[root@server1 docker]# docker build -t demo:v2 . #創建v2
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM busybox
---> 69593048aa3a
Step 2/3 : RUN touch file2
---> Running in 4ab4ecbb36c9
Removing intermediate container 4ab4ecbb36c9
---> a82b29235c1d
Step 3/3 : RUN mkdir redhat
---> Running in 312a217cc548
Removing intermediate container 312a217cc548
---> 57b33e754a66
Successfully built 57b33e754a66
Successfully tagged demo:v2
[root@server1 docker]# docker history demo:v1 #查看容器的層數
[root@server1 docker]# docker history demo:v2
[root@server1 docker]# docker images #查看有幾個容器



四、Dockerfile
1.常用指令
用來提交創建鏡像
FROM #指定base鏡像,如果本地不存在會從遠程倉庫下載,
MAINTAINER #設定鏡像的作者,比如用戶郵箱等,
COPY
#把檔案從build context復制到鏡像
#支持兩種形式:COPY src dest 和 COPY ["src", "dest"]
#src必須指定build context中的檔案或目錄
ADD
#用法與COPY類似,不同的是src可以是歸檔壓縮檔案,檔案會被自動解壓到dest,也可以自動下載URL并拷貝到鏡像:
#ADD html.tar /var/www
#ADD http://ip/html.tar /var/www
ENV
#設定環境變數,變數可以被后續的指令使用:
#ENV HOSTNAME sevrer1.example.com
EXPOSE
#如果容器中運行應用服務,可以把服務埠暴露出去:
EXPOSE 80
VOLUME
#申明資料卷,通常指定的是應用的資料掛在點:
VOLUME ["/var/www/html"]
WORKDIR
#為RUN、CMD、ENTRYPOINT、ADD和COPY指令設定鏡像中的當前作業目錄,如果目錄不存在會自動創建,
RUN
# 在容器中運行命令并創建新的鏡像層,常用于安裝軟體包:
RUN yum install -y vim
CMD 與 ENTRYPOINT
#這兩個指令都是用于設定容器啟動后執行的命令,但CMD會被docker run后面的命令列覆寫,而ENTRYPOINT不會被忽略,一定會被執行,
#docker run后面的引數可以傳遞給ENTRYPOINT指令當作引數,
#Dockerfile中只能指定一個ENTRYPOINT,如果指定了很多,只有最后一個有效,
Shell和exec格式的區別
# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT echo "hello, $name"
Shell格式底層會呼叫/bin/sh -c來執行命令,可以決議變數,而下面
的exec格式不會:
# cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", "hello, $name"]
2.通過Dockerfile檔案封裝nginx鏡像
[root@server1 ~]# cd docker/
## 1.下載nginx安裝包
[root@server1 docker]# lftp 172.25.15.250
lftp 172.25.15.250:~> cd pub/docs/lamp/
lftp 172.25.15.250:/pub/docs/lamp> get nginx-1.20.1.tar.gz
1061461 bytes transferred
lftp 172.25.15.250:/pub/docs/lamp> exit
[root@server1 docker]# ls
Dockerfile nginx-1.20.1.tar.gz
## 2.軟體倉庫的配置
[root@server1 docker]# cp /etc/yum.repos.d/westos.repo .
[root@server1 docker]# ls
Dockerfile nginx-1.20.1.tar.gz westos.repo
[root@server1 docker]# cat westos.repo
[wan]
name="wan"
baseurl=http://172.25.15.250/rhel7
gpgcheck=0
[docker]
name=docker
baseurl=ftp://172.25.15.250/pub/docs/docker/docker-ce
gpgcheck=0
## 3.下載rhel7鏡像
[root@server1 docker]# lftp 172.25.15.250
lftp 172.25.15.250:~> cd pub/images/
lftp 172.25.15.250:/pub/images> get rhel7.tar
147112448 bytes transferred
lftp 172.25.15.250:/pub/images> exit
[root@server1 docker]# ls
Dockerfile nginx-1.20.1.tar.gz rhel7.tar westos.repo


## 4.匯入鏡像,封裝
[root@server1 docker]# docker load -i rhel7.tar #匯入
e1f5733f050b: Loading layer 147.1MB/147.1MB
[root@server1 docker]# vim Dockerfile #撰寫Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY westos.repo /etc/yum.repos.d/
ADD nginx-1.20.1.tar.gz /mnt
RUN rpmdb --rebuilddb
RUN yum install -y gcc pcre-devel zlib-devel make
WORKDIR /mnt/nginx-1.20.1
RUN ./configure &> /dev/null
RUN make &> /dev/null
RUN make install &> /dev/null
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v1 . #封裝容器rhel7:v1
[root@server1 docker]# docker run -d --name rhel7 rhel7:v1 #運行
[root@server1 docker]# docker inspect rhel7 #查看容器資訊
[root@server1 docker]# cd /var/lib/docker/volumes /9b855292b296fd0d4fe423342e52dc5ea5d9d190e7ab9cf131ceef7f95637577/_data #進入目錄
[root@server1 _data]# ls
[root@server1 _data]# echo www.jwl.org > index.html #撰寫nginx默認發布檔案
[root@server1 _data]# curl 172.17.0.2 #訪問查看
www.jwl.org
[root@server1 _data]#




[root@server1 _data]# docker images

我們看到封裝好的v1有303MB,對于企業來說過大,因此我們要進行優化,
五、優化容器
1.第一種:簡單優化,減少鏡像層數
清理鏡像構建的中間產物
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7 as build
COPY westos.repo /etc/yum.repos.d/
ADD nginx-1.20.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.20.1
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel &> /dev/null && ./configure &> /dev/null && make &> /dev/null && make install &> /dev/null && rm -fr /mnt/nginx-1.20.1 && yum remove -y gcc make && yum clean all
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v2 .
[root@server1 docker]# docker run -d --name rhel7.1 rhel7:v2 #換個名稱運行
[root@server1 docker]# docker images #查看所有容器
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v2 f3c552fd7ff4 3 minutes ago 233MB #和v1比較少了130MB
rhel7 v1 a8e39b9ae36a 46 minutes ago 303MB #未優化
rhel7 latest 0a3eb3fde7fd 7 years ago 140MB #原始鏡像
[root@server1 docker]#



2.第二種:使用多階段構建鏡像
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7 as build
COPY westos.repo /etc/yum.repos.d/
ADD nginx-1.20.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.20.1
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel &> /dev/null && ./configure &> /dev/null && make &> /dev/null && make install &> /dev/null && rm -fr /mnt/nginx-1.20.1 && yum remove -y gcc make && yum clean all
FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v3 .
[root@server1 docker]# docker run -d --name rhel7.2 rhel7:v3
736cd619254c4c157d8402144fff6f15628c56c5b79c571d9b7f321934c77b50
[root@server1 docker]# docker images #V3相比v1和v2更小
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v3 186d48c6f99a 40 seconds ago 144MB ##使用多階段構建鏡像 縮減到了144M,但還是比nginx官方鏡像133M大很多
rhel7 v2 f3c552fd7ff4 8 minutes ago 233MB ##減少鏡像層數,清理鏡像構建的中間產物
rhel7 v1 a8e39b9ae36a 51 minutes ago 303MB #未優化
rhel7 latest 0a3eb3fde7fd 7 years ago 140MB #原始鏡像


3.第三種:更換構建鏡像,選擇最精簡的基礎鏡像
##1.下載鏡像
[root@server1 docker]# ls
Dockerfile nginx-1.20.1.tar.gz rhel7.tar westos.repo
[root@server1 docker]# lftp 172.25.15.250
lftp 172.25.15.250:~> cd pub/images/
lftp 172.25.15.250:/pub/images> get base-debian10.tar
20818944 bytes transferred
lftp 172.25.15.250:/pub/images> exit
[root@server1 docker]# ls
base-debian10.tar Dockerfile nginx-1.20.1.tar.gz rhel7.tar westos.repo
[root@server1 docker]# docker load -i base-debian10.tar
de1602ca36c9: Loading layer 3.041MB/3.041MB
1d3b68b6972f: Loading layer 17.77MB/17.77MB
Loaded image: gcr.io/distroless/base-debian10:latest
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v3 186d48c6f99a 6 minutes ago 144MB
rhel7 v2 f3c552fd7ff4 14 minutes ago 233MB
rhel7 v1 a8e39b9ae36a 57 minutes ago 303MB
rhel7 latest 0a3eb3fde7fd 7 years ago 140MB
gcr.io/distroless/base-debian10 latest d48fcdd54946 51 years ago 19.2MB
## 2.封裝
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM nginx:latest as base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONE
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/ld-* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /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-debian10
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t rhel7:v4 .
[root@server1 docker]# docker run -d --name rhel7.3 rhel7:v4
19cef46b199993e6d1b53da00ad7227170095ef1323e44f5ccb6c16472bceb7e
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v4 dc3e62941331 About a minute ago 31.9MB #更換鏡像,選擇最精簡的基礎鏡像
rhel7 v3 186d48c6f99a 13 minutes ago 144MB #使用多階段構建鏡像 縮減到了144M,但還是比nginx官方鏡像133M大很多
rhel7 v2 f3c552fd7ff4 20 minutes ago 233MB #減少鏡像層數,清理鏡像構建的中間產物
rhel7 v1 a8e39b9ae36a About an hour ago 303MB #未優化
nginx latest 4cdc5dd7eaad 13 days ago 133MB
rhel7 latest 0a3eb3fde7fd 7 years ago 140MB #原始鏡像
gcr.io/distroless/base-debian10 latest d48fcdd54946 51 years ago 19.2MB
[root@server1 docker]#





轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/289531.html
標籤:其他
