docker容器介紹(3)

接上篇docker容器介紹

鏡像遷移

保存一臺宿主機上的鏡像爲tar文件,然後可以導入到其他的宿主機上:

save

​ 將鏡像打包,與下面的load命令相對應

[root@yixuan ~]# docker save -o nginx.tar daocloud.io/library/nginx  

load

​ 與上面的save命令相對應,將上面sava命令打包的鏡像通過load命令導入,(實驗環境中原來機器上面有鏡像可以先刪除掉。)

[root@yixuan ~]# docker load < nginx.tar
[root@yixuan ~]# docker images
把容器導出成tar包 export   import 

把容器做成鏡像  commit  -a "" -m ""  

把鏡像保存爲tar包 save    load

通過Dockerfile創建鏡像

Docker 提供了一種更便捷的方式,叫作 Dockerfile

docker build命令用於根據給定的Dockerfile構建Docker鏡像。

docker build語法:

# docker build [OPTIONS] <PATH | URL | ->
1. 常用選項說明
--build-arg,設置構建時的變量
--no-cache,默認false。設置該選項,將不使用Build Cache構建鏡像
--pull,默認false。設置該選項,總是嘗試pull鏡像的最新版本
--compress,默認false。設置該選項,將使用gzip壓縮構建的上下文
--disable-content-trust,默認true。設置該選項,將對鏡像進行驗證
--file, -f,Dockerfile的完整路徑,默認值爲‘PATH/Dockerfile’
--isolation,默認--isolation="default",即Linux命名空間;其他還有process或hyperv
--label,爲生成的鏡像設置metadata
--squash,默認false。設置該選項,將新構建出的多個層壓縮爲一個新層,但是將無法在多個鏡像之間共享新層;設置該選項,實際上是創建了新image,同時保留原有image。
--tag, -t,鏡像的名字及tag,通常name:tag或者name格式;可以在一次構建中爲一個鏡像設置多個tag
--network,默認default。設置該選項,Set the networking mode for the RUN instructions during build
--quiet, -q ,默認false。設置該選項,Suppress the build output and print image ID on success
--force-rm,默認false。設置該選項,總是刪除掉中間環節的容器
--rm,默認--rm=true,即整個構建過程成功後刪除中間環節的容器
示例: 
docker build -t soso/bbauto:v2.1 .

docker build  是docker創建鏡像的命令 
-t 是標識新建的鏡像屬於 soso的 bbauto鏡像 
:v2 是tag 
"."是用來指明 我們的使用的Dockerfile文件當前目錄的 

2.1、 創建鏡像所在的文件夾和Dockerfile文件

[root@yixuan ~]# mkdir sinatra
[root@yixuan ~]# cd sinatra/
[root@yixuan sinatra]# touch Dockerfile

2.2、 在Dockerfile文件中寫入指令,每一條指令都會更新鏡像的信息例如:

[root@yixuan sinatra]# vim Dockerfile
#This is a comment 
FROM daocloud.io/library/centos:7
MAINTAINER soso soso@yixuan
RUN yum install -y wget
RUN touch a.txt
RUN mkdir /test

格式說明:

命令要大寫,"#"是註解。 
每一個指令後面需要跟空格,語法。
FROM 命令是告訴docker 我們的鏡像什麼從哪裏下載。 
MAINTAINER 是描述 鏡像的創建人。 
RUN 命令是在鏡像內部執行。就是說他後面的命令應該是針對鏡像可以運行的命令。 

2.3、創建鏡像

命令:
# docker build -t soso/centso:7 . 

docker build  是docker創建鏡像的命令  

詳細執行過程:

[root@yixuan sinatra]# docker build -t soso/centos:7 . 
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM daocloud.io/library/centos
latest: Pulling from library/centos
d8d02d457314: Pull complete 
Digest: sha256:a36b9e68613d07eec4ef553da84d0012a5ca5ae4a830cf825bb68b929475c869
Status: Downloaded newer image for daocloud.io/library/centos:latest
 ---> 67fa590cfc1c
Step 2/4 : MAINTAINER soso soso@yixuan
 ---> Running in aab3d80939d8
Removing intermediate container aab3d80939d8
 ---> 12bae7d75a23
Step 3/4 : RUN yum update && yum install -y epel*
 ---> Running in ad83c387c60f
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
Resolving Dependencies
--> Running transaction check
---> Package audit-libs.x86_64 0:2.8.4-4.el7 will be updated
---> Package audit-libs.x86_64 0:2.8.5-4.el7 will be an update

2.4、創建完成後,從鏡像創建容器

在這裏插入圖片描述

在這裏插入圖片描述

Dockerfile實例:容器化python的flask應用

目標: 用 Docker 部署一個用 Python 編寫的 Web 應用。

首先部署整個流程:

基礎鏡像(python)-->flask-->部署python應用
web框架 flask django

代碼功能:

​ 如果當前環境中有"NAME"這個環境變量,就把它打印在"Hello"後,否則就打印"Hello world",最後再打印出當前環境的 hostname。

[root@yixuan ~]# mkdir python_app
[root@yixuan ~]# cd python_app/
[root@yixuan python_app]# vim app.py
from flask import Flask
import socket
import os

app = Flask(__name__)

@app.route('/')
def hello():
    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

應用依賴:

定義在同目錄下的 requirements.txt 文件裏,內容如下:

[root@yixuan python_app]# vim requirements.txt
Flask 

Dockerfile製作容器鏡像:

# vim Dockerfile
FROM python:2.7-slim
WORKDIR /app
ADD . /app
RUN pip install --trusted-host pypi.python.org -r requirements.txt
EXPOSE 80
ENV NAME World
CMD ["python", "app.py"]

Dockerfile文件說明:

FROM python:2.7-slim
# 使用官方提供的 Python 開發鏡像作爲基礎鏡像 
# 指定"python:2.7-slim"這個官方維護的基礎鏡像,從而免去安裝 Python 等語言環境的操作。:

WORKDIR /app
# 將工作目錄切換爲 /app,意思是在這一句之後,Dockerfile 後面的操作都以這一句指定的 /app 目錄作爲當前目錄。 

ADD . /app
# 將當前目錄下的所有內容複製到 /app 下 Dockerfile 裏的原語並不都是指對容器內部的操作。比如 ADD,指的是把當前目錄(即 Dockerfile 所在的目錄)裏的文件,複製到指定容器內的目錄當中。

RUN pip install --trusted-host pypi.python.org -r requirements.txt
# 使用 pip 命令安裝這個應用所需要的依賴

EXPOSE 80
# 允許外界訪問容器的 80 端口

ENV NAME World
# 設置環境變量

CMD ["python", "app.py"]
# 設置容器進程爲:python app.py,即:這個 Python 應用的啓動命令,這裏app.py 的實際路徑是 /app/app.py。CMD ["python", "app.py"] 等價於 "docker run python app.py"。 

現在目錄結構:

[root@yixuan python_app]# ls
Dockerfile  app.py   requirements.txt 

構建鏡像:

[root@yixuan python_app]# docker build -t testpython .
-t  給這個鏡像加一個 Tag

Dockerfile 中的每個原語執行後,都會生成一個對應的鏡像層。即使原語本身並沒有明顯地修改文件的操作(比如,ENV 原語),它對應的層也會存在。只不過在外界看來,這個層是空的。

查看結果:

[root@yixuan python_app]# docker images
REPOSITORY                              TAG                 IMAGE ID           ...
testpython                              latest              16bc21f3eea3

啓動容器:

[root@yixuan python_app]# docker run -it -p 4000:80 testpython /bin/bash

查看容器:

[root@yixuan python_app]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED                  
ce02568e64ce        testpython          "/bin/bash"         About a minute ago

進入容器:

[root@yixuan python_app]# docker exec -it ce02568 /bin/bash 
root@ce02568e64ce:/app# python app.py &        #將python運行起來

訪問容器內應用:

[root@yixuan ~]# curl http://localhost:4000
<h3>Hello World!</h3><b>Hostname:</b> f201f6855136<br/>

實戰練習

1.創建一個nginx的dockerfile
[root@yixuan ~]# mkdir nginx  
[root@yixuan ~]# cd nginx/
[root@yixuan nginx]# vim Dockerfile
# This my first nginx Dockerfile
# Version 1.0
FROM daocloud.io/library/centos:7
MAINTAINER yixuan
ENV PATH /usr/local/nginx/sbin:$PATH
ADD nginx-1.16.1.tar.gz /usr/local/
ADD epel-release-7-11.noarch.rpm /usr/local/
RUN rpm -ivh /usr/local/epel-release-7-11.noarch.rpm
RUN yum install -y gcc gcc-c++ make && yum -y install openssl openssl-devel && yum install -y zlib zlib-devel && yum clean all
RUN useradd -s /sbin/nologin -M www
WORKDIR /usr/local/nginx-1.16.1
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www && make && make install
RUN echo "daemon off;" >> /etc/nginx.conf
EXPOSE 80
CMD /bin/sh -c 'nginx -g "daemon off;"'  #放後臺啓動

[root@yixuan nginx]# ls   #將nginx的tar包與epel源上傳到nginx目錄下面
Dockerfile  epel-release-7-11.noarch.rpm  nginx-1.16.1.tar.gz
[root@yixuan nginx]# pwd
/root/nginx
[root@yixuan nginx]# docker build -t nginx:v7.1 .
[root@yixuan nginx]# docker run -itd --name nginx9 -p 8088:80 nginx:v7.1  #啓動容器
[root@yixuan nginx]# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
fec1f3a37cb0        nginx:v7.1          "/bin/sh -c '/bin/sh…"   6 seconds ago       Up 5 seconds        0.0.0.0:8088->80/tcp

在這裏插入圖片描述

2.創建一個jenkins的Dockerfile
[root@yixuan ~]# mkdir tomcat 
[root@yixuan ~]# cd tomcat/
[root@yixuan tomcat]# vim Dockerfile
# This my first jenkins Dockerfile
# Version 1.0

FROM daocloud.io/library/centos:7
MAINTAINER yixuan
ENV JAVA_HOME /usr/local/jdk1.8.0_211
ENV TOMCAT_HOME /usr/local/apache-tomcat-8.5.47
ENV PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
ADD apache-tomcat-8.5.47.tar.gz /usr/local/
ADD jdk-8u211-linux-x64.tar.gz /usr/local/
RUN rm -rf /usr/local/apache-tomcat-8.5.47/webapps/*
ADD jenkins.war /usr/local/apache-tomcat-8.5.47/webapps
RUN rm -rf apache-tomcat-8.5.47.tar.gz  apache-tomcat-8.5.47.tar.gz
EXPOSE 8080
ENTRYPOINT ["/usr/local/apache-tomcat-8.5.47/bin/catalina.sh","run"]  #運行的命令

[root@yixuan tomcat]# pwd
/root/tomcat
[root@yixuan tomcat]# ls  #將jdk與tomcat還有jenkins的包上傳到tomcat目錄中
apache-tomcat-8.5.47.tar.gz  Dockerfile  jdk-8u211-linux-x64.tar.gz  jenkins.war
[root@yixuan tomcat]# docker build -t jenkins:v1 .
[root@yixuan tomcat]# docker run -itd --name jenkins1 -p 8081:8080 jenkins:v1

在這裏插入圖片描述
擴展----CMD與ENTRYPOINT區別

一、dockerfile中的 CMD

1、每個dockerfile中只能有一個CMD如果有多個那麼只執行最後一個。
2、CMD 相當於啓動docker時候後面添加的參數看,舉個簡單例子:
# docker run -itd --name test image(鏡像) /bin/bash -c
a、鏡像名稱後面跟了一個/bin/bash -c ,其實等價於在dockerfile中的CMD ["/bin/bash","-c"]。
b、如果dockerfile中的CMD中有了CMD["/bin/bash","-c"],那麼就不用在執行的時候再添加了,如果添加了參數的話那麼就相當於要執行你添加的參數,默認的CMD中的參數就無效了。

二、dockerfile中的ENTRYPOINT
1、一個dockerfile中ENTRYPOINT也只能存在一個,若存在多個那麼只執行最後一個,你可以理解爲開機啓動的意思,和CMD有點像,不過還是有區別。

2、舉個簡單例子:
a、dockerfile中有ENTRYPOINT ["tail","-f","/var/log/nginx/access.log"],那麼啓動的時候鏡像就執行了這個裏面的內容,如果你像上面帶參數的話就相當於在這個執行的內容後面再加入參數。
案例:
如果我們的dockerfile中有a中的這句話然後我們啓動我們的docker:
#docker run -itd --name test image(鏡像名) /bin/bash -c

此時就相當於我們啓動docker的時候執行了:tail -f /var/log/nginx/access.log /bin/bash -c
這個命令明顯就不對.

dockerfile優化

編譯一個簡單的nginx成功以後發現好幾百M。

1、RUN 命令要儘量寫在一條裏,每次 RUN 命令都是在之前的鏡像上封裝,只會增大不會減小

2、每次進行依賴安裝後,記得yum clean all【centos】 
#yum clean all 清除緩存中的rpm頭文件和包文件

3、選擇比較小的基礎鏡像。

部署私有倉庫應用

私有倉庫鏡像:

registry --官方出品, 沒有圖形界面.Docker hub官方已提供容器鏡像registry,用於搭建私有倉庫

拉取鏡像:

[root@yixuan ~]# docker pull daocloud.io/library/registry:latest

運行容器:

[root@yixuan ~]# docker run -d -v /home/dockerdata/registry:/var/lib/registry --name "pri_registry" --restart=always -p 5000:5000 daocloud.io/library/registry

參數解釋:
/home/dockerdata/registry表示爲宿主機的目錄,如果不存在自動創建
-v映射目錄:  宿主機的目錄:容器目錄
把宿主機的目錄掛載到容器中,將數據目錄掛載出來就是爲了防止docker私有倉庫這個容器被刪除的時候,倉庫裏面的鏡像也被刪除。
-p 端口映射:本地端口:容器端口

​ 注:如果創建容器不成功,報錯防火牆,解決方案如下

#systemctl stop firewalld
#yum install iptaqbles*
#systemctl start iptables
#iptables -F
#systemctl restart docker  
[root@yixuan ~]# docker ps 
CONTAINER ID        IMAGE                          COMMAND                  CREATED              STATUS              PORTS                    NAMES
0823df72b160        daocloud.io/library/registry   "/entrypoint.sh /etc…"   About a minute ago   Up About a minute   0.0.0.0:5000->5000/tcp   pri_registry 

連接容器查看端口狀態:

[root@yixuan ~]# docker exec -it  0823df7  /bin/sh
/ # netstat -lntp    #查看5000端口是否開啓
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 :::5000                 :::*                    LISTEN      1/registry
/ #

在本機查看能否訪問該私有倉庫, 看看狀態碼是不是200

[root@yixuan ~]# curl -I http://127.0.0.1:5000
HTTP/1.1 200 OK 

爲了方便,下載1個比較小的鏡像,buysbox

[root@yixuan ~]# docker pull daocloud.io/library/busybox

上傳前必須給鏡像打tag 註明ip和端口:

[root@yixuan ~]# docker tag busybox 192.168.246.141:5000/busybox

宿主機查看目錄:
[root@yixuan ~]# ls /home/dockerdata/registry/docker/registry/v2/repositories/

下面這個Mysql是我測試的第二個鏡像,從daocloud拉取的:

[root@yixuan ~]# docker pull daocloud.io/library/mysql
[root@yixuan ~]# docker tag daocloud.io/library/mysql 192.168.246.141:5000/daocloud.io/library/mysql
[root@yixuan ~]# docker images

注:tag後面可以使用鏡像名稱也可以使用id,我這裏使用的鏡像名稱,如果使用官方的鏡像,不需要加前綴,但是daocloud.io的得加前綴.

修改請求方式爲http:

默認爲https,不改會報以下錯誤:
Get https://master.up.com:5000/v1/_ping: http: server gave HTTP response to HTTPS client

[root@yixuan ~]# vim /etc/docker/daemon.json    #不存在則創建
{ "insecure-registries":["192.168.246.141:5000"] }

重啓docker:
[root@yixuan ~]# systemctl restart docker

上傳鏡像到私有倉庫:

[root@yixuan ~]# docker push 192.168.246.141:5000/busybox
[root@yixuan ~]# docker push 192.168.246.141:5000/daocloud.io/library/mysql

查看私有倉庫裏的所有鏡像:

語法: # curl  http://ip:port/v2/repo名字/tags/list
[root@yixuan ~]# curl http://192.168.246.141:5000/v2/busybox/tags/list
{"name":"busybox","tags":["latest"]}

[root@yixuan ~]# curl http://192.168.246.141:5000/v2/daocloud.io/library/mysql/tags/list
{"name":"daocloud.io/library/mysql","tags":["latest"]} 

這條命令會查看倉庫下面所有的鏡像:
[root@yixuan ~]# curl http://192.168.246.141:5000/v2/_catalog

拉取鏡像測試:

1.先將剛纔打了tags的鏡像刪掉
[root@yixuan ~]# docker rmi 192.168.246.141:5000/busybox
2.拉取鏡像:
[root@yixuan ~]# docker pull 192.168.246.141:5000/busybox
[root@yixuan ~]# docker images

部署docker web ui應用

下載並運行容器:

[root@yixuan ~]# docker pull uifd/ui-for-docker
[root@yixuan ~]# docker run -it -d --name docker-web -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock docker.io/uifd/ui-for-docker

瀏覽器訪問測試:

​ ip:9000

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章