s3 Docker的映象和容器
阿新 • • 發佈:2018-11-07
Docker技術裡最為基礎的兩大概念:映象和容器。映象的 獲取方式:從
re
gistry拉取,從Dockerfile構建;容器的基本操作
Docker Engine
Docker Architecture
底層技術支援
Image的獲取
Build from Dockerfile
Pull from Registry
通過Image建立(copy) 在Image layer之上建立一個 container layer(可讀寫) 類比面向物件:類和例項 Image負責app的儲存和分 發,Container負責執行app
FROM儘量使用官方的image作為base image!
LABEL 標籤描述
LABEL Metadata不可少!
RUN RUN yum update && yum install-y vim\ python-dev#反斜線換行 RUN apt-get update && apt-get install-y perl\ pwgen --no-install -recommends && rm -rf\ /var/lib/apt/lists/* #注意清理cache RUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'
RUN為了美觀,複雜的RUN用反斜線換行 避免無用分層,合併多條命令成一行
WORKDIR WORKDIR /root WORKDIR /test#如果沒有會自動建立test目錄 WORKDIR demo RUN pwd #輸出結果應該是/test/demo
用WORKDIR,不要用RUN cd! 儘量使用絕對目錄!
ADD and COPY
ADD hello / ADD test.tar.gz / #新增到根目錄並解壓 WORKDIR /root ADD hello test/ #/root/test/hello WORKDIR /root COPY hello test/ ADD or COPY 大部分情況,COPY優於ADD! ADD 除了COPY還有額外功能(解壓) 新增遠端檔案/目錄使用curl或者wget
ENV ENV MYSQL_VERSION 5.6 #設定常量 RUN apt-get install-y mysql-server= "${MYSQL_VERSION} "\ && rm -rf /var/lib/apt/lists/* #引用常量
儘量使用ENV增加可維護性 VOLUME and EXPOSE (儲存和網路)
https://github.com/docker-library/mysql/blob/master/5.7/Dockerfile https:/docs.docker.com/engine/reference/builder/#cmd
RUN:執行命令並建立新的 Image Layer CMD:設定容器啟動後預設執行的命令和引數 ENTRYPOINT:設定容器啟動時執行的命令
CMD and ENTRYPOINT
CMD ◆容器啟動時預設執行的命令 ◆如果docker run指定了其它命令,CMD命令被忽略 ◆如果定義了多個CMD,只有最後一個會執行
ENTRYPOINT
◆讓容器以應用程式或者服務的形式執行 ◆不會被忽略,一定會執行 ◆實踐:寫一個shell指令碼作為entrypoint COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] EXPOSE 27017 CMD [“mongod"]
[[email protected] localhost hello-world]$ docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: Password:
[ [email protected] localhost hello-world]$ docker push fadewalk/hello-world:latest The push refers to repository [ docker. io/ fadewalk/hello-worl] e9b1612d382b: Pushed latest: digest: sha256: db345c850b25406fb24a0d7151e73155d9d1489f22bd8b182b0c010de2d4c5d7 size:527
https://github.com/smartbgp/dockerfiles
拉取私有倉庫映象
[[email protected] hello-world]$ docker build -t 10.75.xx.222:5000/hello-world. Sending build context to Docker daemon 847.9kB Step 1/3:FROM scratch Step 2/3:ADD hello/ --->8ff0b72f198c Step 3/3:CMD["/hello] -->Running in df848216f04a Removing intermediate container df848216f04a --->e97f8b5f0981 Successfully built e97f8b5f0981 Successfully tagged 10.75.44.222:5000/hello-world:latest
push到私有倉庫 [[email protected] hello-world]$ docker push 10.75.xx.222:5000/hello-world [[email protected] hello-world]$ sudo more /etc/docker/daemon.json |"insecure-registries":["10.75.xx.222:5000]}
驗證api
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=5000)
FROM python:2.7 LABEL maintainer="fade" RUN pip install flask COPY app.py /app/ WORKDIR /app EXPOSE 5000 CMD ["python", "app.py"]
docker build -t kevin/flask-hello-world . # build 一個容器
在建立容器過程中(失敗的時候),可以通過中間態的容器id,檢視中間態的容器
docker exec -it 11a767d3a588 python # 中間態容器id
docker inspect 5f6ab6f95518 # 檢視容器 docker logs 5f6ab6f95518 # 檢視 執行日誌
壓力測試軟體 stress --vm 1 --vm-bytes 500000M --verbose
建立壓力測試image FROM ubuntu RUN apt-get update && apt-get install -y stress ENTRYPOINT ["/usr/bin/stress"] # 建立容器就會執行 類似init CMD [] # 建立好後執行的命令,類似 rc.local # 傳入的引數
分配記憶體。 當只設置記憶體時,虛擬記憶體跟前者一樣 docker run --memory=200M kevin/ubuntu-stress --vm 1 --verbose # 顯示過程
設定 --cpu-shares 為佔CPU資源的(%) 相對權重 docker run --cpu-shares=10 --name=test1 xiaopeng163/ubuntu-stress --cpu 1 stress:info:[1] dispatching hogs:1 cpu,0io,0 vm,0 hdd
1 Docker架構和底層技術簡介
Docker Platform
- Docker提供了一個開發,打包,執行app的平臺
- 把app和底層infrastructure隔離開來
Docker Engine
- 後臺程序(dockerd)
- REST API Server
- CLI介面(docker)
Docker Architecture
底層技術支援
- Namespaces:做隔離pid,net,ipc,mnt,uts
- Control groups:做資源限制
- Union file systems:Container和image的分層
2 Docker Image概述
Image 是檔案和 meta data的集合(root filesystem) 分層的,並且每一層都可以新增改變刪除檔案,成為一個新的image 不同的image可以共享相同的layer Image本身是read-only的3 Container
通過Image建立(copy) 在Image layer之上建立一個 container layer(可讀寫) 類比面向物件:類和例項 Image負責app的儲存和分 發,Container負責執行app
[[email protected] ~]# docker ps -aqdocker ps -aq 批量刪除41085d1b95c0 abb8db5ee1c5 b1b0babbe76a c1b9dbf8fc48 d5c6d17741c0 批量刪除 [[email protected] ~]$ docker rm $(docker container ls -aq) 4e540bbeeeb7 5f1c4f401024 6d3466972716 06db5785577c 32f005c8b20b [[email protected] ~]$ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED NAMES 刪除已經退出的容器 [[email protected] ~]# docker rm $(docker ps -f "status=exited" -q) 41085d1b95c0 abb8db5ee1c5 b1b0babbe76a c1b9dbf8fc48 d5c6d17741c0 構建自己的Docker映象 docker container commit # 提交修改後的容器為映象 docker image build = docker build
4 Dockerfile語法
FROMFROM scratch #製作base image FROM centos #使用base image FROM ubuntu:14.04
FROM儘量使用官方的image作為base image!
LABEL 標籤描述
LABEL maintainer="fadewalk" LABEL version="1.0" LABEL description="This is description"
LABEL Metadata不可少!
RUN RUN yum update && yum install-y vim\ python-dev#反斜線換行 RUN apt-get update && apt-get install-y perl\ pwgen --no-install -recommends && rm -rf\ /var/lib/apt/lists/* #注意清理cache RUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'
RUN為了美觀,複雜的RUN用反斜線換行 避免無用分層,合併多條命令成一行
WORKDIR WORKDIR /root WORKDIR /test#如果沒有會自動建立test目錄 WORKDIR demo RUN pwd #輸出結果應該是/test/demo
用WORKDIR,不要用RUN cd! 儘量使用絕對目錄!
ADD and COPY
ADD hello / ADD test.tar.gz / #新增到根目錄並解壓 WORKDIR /root ADD hello test/ #/root/test/hello WORKDIR /root COPY hello test/ ADD or COPY 大部分情況,COPY優於ADD! ADD 除了COPY還有額外功能(解壓) 新增遠端檔案/目錄使用curl或者wget
ENV ENV MYSQL_VERSION 5.6 #設定常量 RUN apt-get install-y mysql-server= "${MYSQL_VERSION} "\ && rm -rf /var/lib/apt/lists/* #引用常量
儘量使用ENV增加可維護性 VOLUME and EXPOSE (儲存和網路)
https://github.com/docker-library/mysql/blob/master/5.7/Dockerfile https:/docs.docker.com/engine/reference/builder/#cmd
RUN:執行命令並建立新的 Image Layer CMD:設定容器啟動後預設執行的命令和引數 ENTRYPOINT:設定容器啟動時執行的命令
Shell和Exec格式
Shell格式RUN apt-get install -y vim CMD echo "hello docker" ENTRYPOINT echo "hello docker"Exec格式
RUN ["apt-get","install","-y","vim"] CMD ["/bin/echo","hello docker"] ENTRYPOINT ["/bin/echo","hello docker"]
CMD and ENTRYPOINT
CMD ◆容器啟動時預設執行的命令 ◆如果docker run指定了其它命令,CMD命令被忽略 ◆如果定義了多個CMD,只有最後一個會執行
ENTRYPOINT
◆讓容器以應用程式或者服務的形式執行 ◆不會被忽略,一定會執行 ◆實踐:寫一個shell指令碼作為entrypoint COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] EXPOSE 27017 CMD [“mongod"]
5 映象的釋出
[[email protected] localhost hello-world]$ docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: Password:
[ [email protected] localhost hello-world]$ docker push fadewalk/hello-world:latest The push refers to repository [ docker. io/ fadewalk/hello-worl] e9b1612d382b: Pushed latest: digest: sha256: db345c850b25406fb24a0d7151e73155d9d1489f22bd8b182b0c010de2d4c5d7 size:527
https://github.com/smartbgp/dockerfiles
私有倉庫搭建
參考官方文件 Docker Registry This image contains an implementation of the Docker Registry HTTP API V2 for use with Docker 1.6+.Se github.com/docker/distribution for more details about what it is. $docker run-d-p 5000:5000 --restart always --name registry registry:2 Now,use it from within Docker:拉取私有倉庫映象
[[email protected] hello-world]$ docker build -t 10.75.xx.222:5000/hello-world. Sending build context to Docker daemon 847.9kB Step 1/3:FROM scratch Step 2/3:ADD hello/ --->8ff0b72f198c Step 3/3:CMD["/hello] -->Running in df848216f04a Removing intermediate container df848216f04a --->e97f8b5f0981 Successfully built e97f8b5f0981 Successfully tagged 10.75.44.222:5000/hello-world:latest
push到私有倉庫 [[email protected] hello-world]$ docker push 10.75.xx.222:5000/hello-world [[email protected] hello-world]$ sudo more /etc/docker/daemon.json |"insecure-registries":["10.75.xx.222:5000]}
驗證api
6 Dockerfile 練習1
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=5000)
FROM python:2.7 LABEL maintainer="fade" RUN pip install flask COPY app.py /app/ WORKDIR /app EXPOSE 5000 CMD ["python", "app.py"]
docker build -t kevin/flask-hello-world . # build 一個容器
在建立容器過程中(失敗的時候),可以通過中間態的容器id,檢視中間態的容器
docker exec -it 11a767d3a588 python # 中間態容器id
docker inspect 5f6ab6f95518 # 檢視容器 docker logs 5f6ab6f95518 # 檢視 執行日誌
7 Dockerfile 練習2
壓力測試軟體 stress --vm 1 --vm-bytes 500000M --verbose
建立壓力測試image FROM ubuntu RUN apt-get update && apt-get install -y stress ENTRYPOINT ["/usr/bin/stress"] # 建立容器就會執行 類似init CMD [] # 建立好後執行的命令,類似 rc.local # 傳入的引數
分配記憶體。 當只設置記憶體時,虛擬記憶體跟前者一樣 docker run --memory=200M kevin/ubuntu-stress --vm 1 --verbose # 顯示過程
設定 --cpu-shares 為佔CPU資源的(%) 相對權重 docker run --cpu-shares=10 --name=test1 xiaopeng163/ubuntu-stress --cpu 1 stress:info:[1] dispatching hogs:1 cpu,0io,0 vm,0 hdd