相比於傳統: 部署很是慢 成本很是高 資源浪費 難於遷移和擴展 可能會被限定硬件廠商
因爲物理機的諸多問題,後來出現了虛擬機python
一個物理機能夠部署多個app,每一個app獨立運行在一個VM裏。mysql
可是虛擬化也是有侷限性的,每個虛擬機都是一個完整的操做系統,要分配系統資源,虛擬機多道程度時,操做系統自己資源也就消耗殆盡,或者說必須擴容。linux
因爲環境部署配置的麻煩,出現瞭如下程序員
特性 | 容器 | 虛擬機 |
---|---|---|
啓動 | 秒級 | 分鐘級 |
硬盤使用 | 通常爲 MB | 通常爲 GB |
性能 | 接近原生 | 弱 |
系統支持量 | 單機支持上千個容器 | 通常幾十個 |
1)資源佔用多web
虛擬機會獨佔一部份內存和硬盤空間。它運行的時候,其餘程序就不能使用這些資源了。哪怕虛擬機裏面的應用程序,真正使用的內存只有 1MB,虛擬機依然須要幾百 MB 的內存才能運行。redis
(2)冗餘步驟多sql
虛擬機是完整的操做系統,一些系統級別的操做步驟,每每沒法跳過,好比用戶登陸。docker
(3)啓動慢django
啓動操做系統須要多久,啓動虛擬機就須要多久。可能要等幾分鐘,應用程序才能真正運行。json
(1)啓動快
容器裏面的應用,直接就是底層系統的一個進程,而不是虛擬機內部的進程。因此,啓動容器至關於啓動本機的一個進程,而不是啓動一個操做系統,速度就快不少。
(2)資源佔用少
容器只佔用須要的資源,不佔用那些沒有用到的資源;虛擬機因爲是完整的操做系統,不可避免要佔用全部資源。另外,多個容器能夠共享資源,虛擬機都是獨享資源。
(3)體積小
容器只要包含用到的組件便可,而虛擬機是整個操做系統的打包,因此容器文件比虛擬機文件要小不少。
總之,容器有點像輕量級的虛擬機,可以提供虛擬化的環境,可是成本開銷小得多。
說的通俗點:Docker做用
解決環境部署問題,基於一個鏡像文件,可以運行出容器示例,就不須要作環境部署。
更高效的利用系統資源 因爲容器不須要進行硬件虛擬以及運行完整操做系統等額外開銷,Docker 對系統 資源的利用率更高。 不管是應用執行速度、內存損耗或者文件存儲速度,都要比傳 統虛擬機技術更高效。所以,相比虛擬機技術,一個相同配置的主機,每每能夠運 行更多數量的應用。
更快速的啓動時間 傳統的虛擬機技術啓動應用服務每每須要數分鐘,而 Docker 容器應用,因爲直接 運行於宿主內核,無需啓動完整的操做系統,所以能夠作到秒級、甚至毫秒級的啓 動時間。大大的節約了開發、測試、部署的時間。
一致的運行環境 開發過程當中一個常見的問題是環境一致性問題。因爲開發環境、測試環境、生產環 境不一致,致使有些 bug 並未在開發過程當中被發現。 而 Docker 的鏡像提供了除內 核外完整的運行時環境,確保了應用運行環境一致性,從而不會再出現 「這段代碼 在我機器上沒問題啊」 這類問題。
持續交付和部署 對開發和運維(DevOps)人員來講,最但願的就是一次建立或配置,能夠在任意 地方正常運行。 使用 Docker 能夠經過定製應用鏡像來實現持續集成、持續交付、部署。開發人員 能夠經過 Dockerfile 來進行鏡像構建,並結合 持續集成(Continuous Integration) 系 統進行集成測試, 而運維人員則能夠直接在生產環境中快速部署該鏡像,甚至結合 持續部署(Continuous Delivery/Deployment) 系統進行自動部署。 並且使用 Dockerfile 使鏡像構建透明化,不只僅開發團隊能夠理解應用運行環 境,也方便運維團隊理解應用運行所需條件,幫助更好的生產環境中部署該鏡像。
更輕鬆的遷移 因爲 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 能夠在 不少平臺上運行,不管是物理機、虛擬機、公有云、私有云,甚至是筆記本,其運 行結果是一致的。 所以用戶能夠很輕易的將在一個平臺上運行的應用,遷移到另外一 個平臺上,而不用擔憂運行環境的變化致使應用沒法正常運行的狀況。
1.yum安裝,配置yum倉庫 -阿里雲倉庫,清華源倉庫,163倉庫, 問題是,docker的版本可能很低,有不少漏洞 -選擇軟件官方提供的yum倉庫,版本都是最新的,可是可能下載較慢 -因爲網速問題,學習階段仍是使用阿里雲的docker [root@xujunk ~]#yum install docker -y 2.rpm 不推薦 3.源碼編譯安裝,很麻煩,若是沒有特定需求,仍是選擇yum
yum remove docker* docker-* -y
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
systemctl status/start/stop docker
[root@xujunk ~]#docker images #列出當前全部的鏡像文件 [root@xujunk ~]#docker run hello-world #運行鏡像文件,生成docker容器實例,docker run命令,會自動下載不存在的鏡像 #容器是隨時建立,隨時刪除的,輕量級,每次docker run 都會生成新的容器記錄 #docker容器進程,若是沒有在後臺運行的話,就會當即掛掉, (容器中必須有正在工做的進程) #運行一個一直活着的容器進程 docker run -d centos /bin/sh -c "while true;do echo '你個糟老頭子,不聽課,壞得很'; sleep 1;done"
docker rmi 鏡像名字/鏡像id #刪除鏡像文件 docker rm 容器id/容器進程名字 #刪除容器記錄 docker rmi -f #強制刪除鏡像文件 docker rm `docker ps -aq` #批量刪除容器記錄,只能刪除掛掉的容器記錄
#docker容器進程的啓停命令 docker start 容器id docker stop 容器id
docker search 鏡像文件名字 #搜索鏡像文件 docker images #列出當前全部的鏡像文件 docker ps #列出當前記錄正在運行的容器進程 docker ps -a #列出全部的容器進程,以及掛掉的 docker logs 容器id #查看容器內的日誌信息 docker logs -f 容器id #檢測容器內的日誌 docker ps -aq #列出全部容器id #進入容器空間內的命令 docker exec -it 容器id /bin/bash #進入容器空間內 -i 交互式命令操做 -t 開啓一個新的終端 #退出容器 exit #運行一個ubuntu容器 docker run -it ununtu cat /etc/os-release #查看一個系統版本
1.ps -a #查看是否有用此鏡像運行中的容器 2.docker stop 容器id #將啓動中的容器關閉 2.docker ps -a #查看全部的容器進程,以及掛掉的 4.docker rm 容器id #刪除殘留容器 5.docker rmi 鏡像文件名字 #刪除鏡像文件
#過程實現 #運行出容器實例 二次修改容器實例 提交容器實例爲新的鏡像 導出鏡像 發給別人導入 1.docker run -it centos /bin/bash #進入一個純淨的centos容器空間內,此時是最小化安裝的系統,沒有vim 沒有py3 2.在容器空間內 yum install vim ,而後退出容器 3.此時這個容器記錄就是攜帶者 vim的容器記錄了(能夠理解爲攜帶者程序依賴,或者python3等等) 4.提交這個容器爲新的 鏡像文件 311110e1ec56 docker commit 容器進程id 鏡像文件的名字 docker commit 419 s21docker-centos-vim #e.g.:[root@xujunk ~]#docker commit 311110e1ec56 docker-centos-vim sha256:d1870159517111e3756f022fdc851a3c90b1bef6daf2c54b4d0a8a3da4224a1 5.導出docker鏡像,成爲一個壓縮文件,能夠發送給你的測試,運維同事了 docker save 鏡像文件名/鏡像id > /opt/centos-vim.tar.gz [root@xujunk ~]#docker save d18701595171 > /opt/centos-vim.tar.gz 6.此時能夠發送文件,給別人導入了 #這裏爲了簡便在本機進行操做,將原鏡像文件刪除 [root@xujunk ~]#docker rmi 鏡像文件id docker load < 同事給你發的鏡像文件 [root@xujunk ~]#docker load < /opt/centos-vim.tar.gz
1.下載一個flask的docker鏡像 [root@xujunk ~]#docker pull training/webapp 2.運行docker鏡像 docker run -d -P -d 後臺運行 -P 隨機端口映射 隨機的宿主機的端口:容器內的端口(自動指定的,由代碼指定) -p 指定端口映射 宿主機的7777:8500 3.建立一個容器空間,而後在裏面執行 python app.py 命令 [root@xujunk ~]#docker run -d -P training/webapp python app.py 建立一個容器空間,而後在裏面執行 python app.py 命令 [root@xujunk ~]#docker run -d -p 6000:5000 training/webapp python app.py 3.查看後臺運行容器端口: [root@xujunk ~]#docker ps """ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1ff5a02461a2 training/webapp "python app.py" 2 minutes ago Up 2 minutes 0.0.0.0:32769->5000/tcp musing_tesla """ 4.訪問這個容器應用 服務器ip:宿主機的映射端口 瀏覽器輸入: 192.168.58.131:32768 5.進入容器空間內,查看代碼
#FROM指令用於 指定容器用什麼發行版 #製做base image 基礎鏡像,儘可能使用官方的image做爲base image FROM scratch #使用base image FROM centos #帶有tag的base image FROM ubuntu:14.04 #定義標籤變量的 LABEL version=「1.0」 #容器元信息,幫助信息,Metadata,相似於代碼註釋 LABEL maintainer="yc_uuu@163.com" #萬能RUN指令,讓容器本身去作些什麼事 #對於複雜的RUN命令,避免無用的分層,多條命令用反斜線換行,合成一條命令! RUN yum update && yum install -y vim \ Python-dev #反斜線換行 RUN /bin/bash -c "source $HOME/.bashrc;echo $HOME」 RUN yum install redis #自動安裝redis WORKDIR /root #至關於linux的cd命令,改變目錄,儘可能使用絕對路徑!!!不要用RUN cd WORKDIR /test #若是沒有就自動建立 WORKDIR demo #再進入demo文件夾 RUN pwd #打印結果應該是/test/demo - 小示例: """ WORKDIR /opt WORKDIR /tmp WORKDIR ../ """ #路徑切換到根目錄 # ADD命令用來 將宿主機的文件添加到容器空間內 #ADD存在壓縮文件解壓的功能,所以,僅僅添加文件到容器內,用COPY而不是ADD ADD and COPY ADD hello / #把本地文件添加到鏡像中,吧本地的hello可執行文件拷貝到鏡像的/目錄 ADD test.tar.gz / #添加到根目錄並解壓 ENV #環境變量,儘量使用ENV增長可維護性 ENV MYSQL_VERSION 5.6 #設置一個mysql常量 示例:RUN yum install -y mysql-server=「${MYSQL_VERSION}」
1.建立一個文件: [root@xujunk opt]#mkdir s21docker [root@xujunk opt]#cd s21docker 2.編寫flask代碼文件 [root@xujunk s21docker]#vim s21flask.py """ from flask import Flask app=Flask(__name__) @app.route('/') def hello(): return "hello docker" if __name__=="__main__": app.run(host='0.0.0.0',port=8080) """ 3.準備Dockerfile (名字必須叫作 Dockerfile) """ FROM centos COPY CentOS-Base.repo /etc/yum.repos.d/ COPY epel.repo /etc/yum.repos.d/ RUN yum clean all RUN yum install python-setuptools -y RUN easy_install flask COPY s21flask.py /opt/ WORKDIR /opt EXPOSE 8080 CMD ["python","s21flask.py"] """ 4.在Dockerfile同級目錄,準備好其餘環境文件,代碼文件:CentOS-Base.repo Dockerfile epel.repo s21flask.py [root@xujunk s21docker]#cp /etc/yum.repos.d/CentOS-Base.repo ./ [root@xujunk s21docker]#cp /etc/yum.repos.d/epel.repo ./ #查看s21docker目錄下文件: [root@xujunk s21docker]#ls CentOS-Base.repo Dockerfile epel.repo s21flask.py 5.構建docker鏡像 docker build -t xujunkai521/s21-flask-docker . docker build 編譯Dockerfile -t 給鏡像加上名字 ,鏡像名字,以倉庫地址開頭,則能夠推送到倉庫中管理 . 找到當前的Dockefile文件 #會按照Dockerfile從上到下一步一步編譯 6.構建完畢以後,查看鏡像文件 [root@xujunk s21docker]#docker images 7.運行這個flask鏡像文件,生成容器實例,代碼就跑在容器中了 [root@xujunk s21docker]#docker run -d -p 9999:8080 指定你要運行的鏡像id/名字 8.web端訪問http://192.168.58.131:9999/ 成功訪問
代碼流程
1.登陸docker帳戶 [root@xujunk s21docker]#docker login 2.修改docker鏡像文件名字,以docker hub帳號開頭 [root@xujunk s21docker]#docker tag docker.io/redis xujunkai521/redis 3.推送鏡像到dockerhub倉庫中,(注意這個是公共倉庫) [root@xujunk s21docker]#docker push xujunkai521/redis
1.下載私有倉庫鏡像文件 [root@xujunk s21docker]# docker run -d \ -p 5000:5000 \ # 宿主機的端口(自定義,本身考慮去分配):容器內暴露的端口(django中寫了 8000),flask 5000 -v /opt/data/registry:/var/lib/registry \ registry -p 表示端口映射 -v 表示宿主機路徑和容器內路徑的映射 2.修改docker的配置文件,支持推送非https的私有鏡像 [root@xujunk s21docker]#cat /etc/docker/daemon.json ,內容以下 { "registry-mirrors": ["http://f1361db2.m.daocloud.io"], "insecure-registries": [ "192.168.58.131:5000" ] } 3.修改docker的啓動文件,加載第二步,修改的配置文件 [root@xujunk s21docker]#vim /lib/systemd/system/docker.service #找到以下的[Service] 代碼塊,添加參數 [Service] EnvironmentFile= -/etc/docker/daemon.json 4.修改了docker配置文件,從新加載docker [root@xujunk s21docker]#systemctl daemon-reload 5.重啓docker服務 [root@xujunk s21docker]#systemctl restart docker 6.因爲重啓了docker,須要從新運行私有倉庫的容器進程 [root@xujunk s21docker]#docker run --privileged=true -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry --privileged=true docker容器的安全機制:設置特權級運行的容器 7.創建完私有云,就上傳一波文件吧! [root@xujunk s21docker]#docker tag docker.io/hello-world 192.168.58.131:5000/hello-666 #把hello-666鏡像 上傳到192.168.58.131:5000路徑 [root@xujunk s21docker]#docker pull 192.168.58.131:5000/hello-666 8.查看瀏覽器: http://192.168.58.131:5000/v2/_catalog
如何要把文件下拉下來,執行下面命令: [root@xujunk s21docker]#docker pull 192.168.58.131:5000/hello-666