|
Docker
|
Openstack
|
部署難度
|
很是簡單,yum安裝docker便可
|
部署複雜,組件較多
|
啓動速度
|
秒級
|
分鐘級
|
處理性能
|
和物理機幾乎一致
|
有必定的性能損失
|
鏡像體積
|
MB級別
|
GB級別
|
管理效率
|
管理簡單 |
管理複雜,組件相互依賴
|
隔離性
|
不徹底隔離
|
完全隔離
|
進程數目
|
單進程、不建議啓動SSH
|
多進程,完整的系統管理
|
網絡鏈接
|
比較弱
|
Neutron組件能夠靈活構建網絡架構 |
cat /etc/redhat-release uname -rm yum install -y docker systemctl start docker ifconfig #docker啓動會建立一個虛擬網卡 docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0 ether 02:42:55:0d:41:e1 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker images #查看當前鏡像 docker search centos #去dockerhub上搜索鏡像 INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED docker.io docker.io/centos The official build of CentOS. 3625 [OK] docker.io docker.io/ansible/centos7-ansible Ansible on Centos7 100 [OK] docker pull centos #獲取鏡像 docker load --input centos.tar # 導入鏡像 docker save -o centos.tar centos # 導出鏡像 docker rmi centos #刪除鏡像 docker run centos /bin/echo "Hello world" # 建立一個容器並運行一條命令 centos是鏡像名稱,名稱必須在全部選項後面 命令能夠有能夠沒有 docker ps -a # 查看容器的狀態 -a表示全部容器,運行和不運行的 默認只顯示運行的容器狀態 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d989b65f0158 centos "/bin/echo 'Hello wor" 2 minutes ago Exited (0) About a minute ago pedantic_banach [root@docker ~]# docker run --name mydocker -t -i centos /bin/bash # 表示啓動一個容器,名稱命名爲mydocker -t分配一個僞終端tty -i表示打開標準輸入 centos是鏡像名稱 /bin/bash 是要執行的命令 若是centos不存在會自動去dockerhub上pull下來 #/bin/bash進程必須分配僞終端才能運行,同時打開標準輸入後才能夠輸入命令 [root@7fbe5da0c90f /]# [root@7fbe5da0c90f /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 02:20 ? 00:00:00 /bin/bash # 正常虛擬機PID=1的程序是systemd或者/sbin/init,顯然docker容器不是虛擬機 root 16 1 0 02:22 ? 00:00:00 ps -ef [root@7fbe5da0c90f /]# cat /proc/cpuinfo # 這裏顯示的是物理機的硬件信息,因此docker並無虛擬出硬件 [root@7fbe5da0c90f /]# exit # 退出容器 [root@docker ~]# docker start mydocker #啓動已經建立好的docker容器,run是建立實例,start是容器關閉後再打開 mydocker是容器名稱,咱們能夠經過ID或名稱來啓動容器 [root@docker ~]# docker --help # 幫助信息 [root@docker ~]# docker attach mydocker # 進入正在運行的容器,須要容器內運行/bin/bash進程 這個命令不靠譜,退出容器後容器就停了 #注:容器內必須有一個前臺進程在運行,不然容器就會中止 更好的進入容器方法是nsenter命令,若是沒有就yum install -y util-linux [root@docker ~]# docker inspect -f "{{.State.Pid}}" mydocker # 獲取容器裏面進程在物理機上的PID,注意要先啓動容器 9515 [root@docker ~]# ps -ef | grep 9515 root 9515 9505 0 11:22 pts/0 00:00:00 /bin/bash root 9553 8900 0 11:22 pts/1 00:00:00 grep --color=auto 9515 [root@docker ~]# nsenter --help [root@docker ~]# nsenter -t 9515 -m -u -i -n -p # 進入容器 [root@7fbe5da0c90f /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 03:22 ? 00:00:00 /bin/bash root 13 0 0 03:51 ? 00:00:00 -bash # nsenter進入後從新建立了bash root 28 13 0 03:54 ? 00:00:00 ps -ef [root@7fbe5da0c90f /]# exit [root@docker ~]# docker ps # nsenter進入而後退出,只是-bash進程結束,/bin/bash進程不會受到影響,因此容器不會關閉 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7fbe5da0c90f centos "/bin/bash" About an hour ago Up 33 minutes mydocker [root@docker ~]# docker exec mydocker whoami # 往docker容器裏面傳遞命令,容器執行後返回結果 root [root@docker ~]# docker exec -it mydocker /bin/bash # 這樣也能進入容器,原理和nsenter不一樣,但效果相同,但建議使用nsenter,這是進入容器的最佳實踐 [root@7fbe5da0c90f /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 03:22 ? 00:00:00 /bin/bash root 50 0 0 04:10 ? 00:00:00 /bin/bash root 62 50 0 04:10 ? 00:00:00 ps -ef [root@docker ~]# docker rm mydocker # 刪除容器,rmi是刪除鏡像 [root@docker ~]# docker rm -f mydocker # 能夠刪除正在運行的容器 -f force強制刪除 [root@docker ~]# docker run --rm centos /bin/echo "hehe" # 啓動一個容器,進程運行完畢後自動刪除 命令總結: 鏡像:docker search # 搜索鏡像 docker pull # 獲取鏡像 docker images # 查看鏡像 docker rmi # 刪除鏡像 docker load --input / docker load < # 導入鏡像 docker save -o # 導出鏡像 容器:docker run --name -h hostname ... # 建立容器 docker start [ID/NAME] # 啓動容器 docker stop [ID/NAME] # 中止容器 docker ps -a # 查看容器 docker exec | docker attach | nsenter # 進入容器 docker rm # 刪除容器
網絡訪問:隨機映射 docker run -P 指定映射 docker run -p hostPort:containerPort docker run -p ip:hostPort:containerPort docker run -p ip::containerPort # 不加端口就隨機 docker run -p hostPort:containerPort:udp docker run -p 81:80 -p 443:443 #Docker網絡訪問 docker啓動時建立了一個橋接網卡docker0 [root@docker ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242550d41e1 no veth1a9fdb5 [root@docker ~]# docker run -d -P nginx # 隨機映射端口 -d 後臺啓動 5038a3bd7de1dd28b303b8a61df12b4352f3e3c0f779ec148106c8ab652ebd45 [root@docker ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5038a3bd7de1 nginx "nginx -g 'daemon off" 43 seconds ago Up 39 seconds 0.0.0.0:32768->80/tcp elated_mcclintock #容器的80端口映射到本地的32768端口,咱們能夠訪問看看 http://172.16.1.5:32768 [root@docker ~]# docker run -d -p 10.0.0.5:82:80 --name mynginx nginx 6386aaef223f9965217053b82dacda0527fbf7edba7da90f0db6ba798cf2b276 [root@docker ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6386aaef223f nginx "nginx -g 'daemon off" About a minute ago Up About a minute 10.0.0.5:82->80/tcp mynginx [root@docker ~]# docker port mynginx # 查看容器端口 80/tcp -> 10.0.0.5:82
[root@docker ~]# vim docker_in.sh #進入docker的腳本 #!/bin/bash # Use nsenter to access docker docker_in(){ NAME_ID=$1 PID=$(docker inspect -f "{{.State.Pid}}" $NAME_ID) nsenter -t $PID -m -u -i -n -p } docker_in $1 [root@docker ~]# chmod +x docker_in.sh [root@docker ~]# ./docker_in.sh mydocker
容器的鏡像是分層的,咱們能夠在一個鏡像基礎上再開發,再生成鏡像,生成的鏡像只保存修改的內容,最終導出的鏡像包含基礎鏡像和添加的鏡像兩層,下載鏡像時也是分層下載。 數據管理:若是要在容器裏寫數據,爲了防止數據寫到一半容器故障,咱們須要將數據寫到物理機上,即須要掛載物理機目錄到docker容器裏即數據卷技術,同時docker支持容器之間的數據卷共享,其它容器經過訪問某個已掛載容器的掛載目錄來間接將數據寫入物理機,即數據卷容器技術。 數據卷 #掛載目錄到容器 [root@docker ~]# docker run -d --name nginx-volumn-test2 -v /data nginx [root@docker ~]# ls /var/lib/docker/volumes/e44afc282ef635422705e42a5292602e4f6ca807a750af2983c86638adbf3751/ _data # 被掛載的源目錄,不指定時源目錄時docker在物理機上自動建立 不一樣的容器對應不一樣的編號 [root@docker ~]# docker run -d --name nginx-volumn-test2 -v /data/docker-volumn-nginx:/data nginx # 指定源目錄 也能夠掛載文件 src:dst [root@docker ~]# docker run -d --name nginx-volumn-test2 -v /data/docker-volumn-nginx:/data:ro nginx #只讀 數據卷容器:掛載了目錄(數據卷)的容器就稱爲數據卷容器。因此能夠專門起一個容器用來掛載,其它的容器直接訪問這個容器而再也不須要掛載 [root@docker volumes]# docker run -it --name volumn-test3 --volumes-from nginx-volumn-test2 centos /bin/bash # --volumes-from 直接訪問另外一個容器的掛載目錄,本身不用掛載。即便test2停了也不影響test3訪問
1.手動構建php
[root@docker ~]# docker ps -a -q # 獲取全部容器的ID e37a40ec1008 2d136a4b9ce8 37a1c1e3e151 b82da6090e37 6386aaef223f 01736bd88a27 5038a3bd7de1 f23d23271be7 7fbe5da0c90f d989b65f0158 [root@docker ~]# docker kill $(docker ps -a -q) # 中止全部容器 [root@docker ~]# docker rm $(docker ps -a -q) # 刪除全部容器 [root@docker ~]# docker run --name mynginx -it centos [root@e570416e1c12 /]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo [root@e570416e1c12 /]# yum install -y nginx [root@e570416e1c12 /]# vi /etc/nginx/nginx.conf daemon off; # 關閉守護進程,就能夠在前臺運行 [root@e570416e1c12 /]# exit [root@docker ~]# docker commit -m "my nginx" e570416e1c12 peter/mynginx:v1 # 提交當前容器狀態,即建立鏡像 跟git很像,git的提交也是對當前目錄狀態作一個鏡像 sha256:390ac6fdc28ae5650673fea9695719c1c3185f7f9cc4eb25233259de158258c0 [root@docker ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE peter/mynginx v1 390ac6fdc28a 3 minutes ago 354.4 MB # peter是倉庫名稱 mynginx是鏡像名稱 v1是標籤 [root@docker ~]# docker run --name mynginxv1 -d -p 81:80 peter/mynginx:v1 nginx # 從鏡像中建立一個容器
2.使用Dockerfile自動構建html
[root@docker nginx]# pwd /opt/dockerfile/nginx [root@docker nginx]# vim Dockerfile # 名稱是固定的 # This Dockerfile #Base image FROM centos #基礎鏡像是什麼即在什麼鏡像基礎上構建 #Maintainer MAINTAINER Peter.Wang #維護者是誰 #Commands RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm RUN yum install -y nginx && yum clean all RUN echo "daemon off;" >> /etc/nginx/nginx.conf ADD index.html /usr/share/nginx/html/index.html # 添加一個文件 EXPOSE 80 # 對外的端口是什麼 CMD ["nginx"] # 啓動時執行的命令是什麼 [root@docker nginx]# echo "nginx in docker hahaha" > index.html # 注意與Dockerfile在同一目錄下 [root@docker nginx]# docker build -t mynginx:v2 . # .表示在當前目錄下找Dockerfile [root@docker nginx]# docker images [root@docker nginx]# docker run --name mynginxv2 -d -p 82:80 mynginx:v2
#分層設計,先構建系統層的鏡像,而後構建運行環境層的鏡像,而後構建應用服務層的鏡像。docker鏡像是分層設計的,而且這種方式使得鏡像能夠重複使用,耦合度較低 [root@docker docker]# tree . ├── app │ ├── xxx-admin │ └── xxx-api ├── runtime │ ├── java │ ├── php │ └── python └── system ├── centos ├── centos-ssh └── ubuntu [root@docker centos]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo [root@docker centos]# cp /etc/yum.repos.d/epel.repo . [root@docker centos]# ls epel.repo
#系統環境centos [root@docker centos]# vim Dockerfile # Docker for CentOS #Base image FROM centos #Maintainer MAINTAINER Peter.Wang xxx@gmail.com #EPEL ADD epel.repo /etc/yum.repos.d/ #Base pkg RUN yum install -y wget mysql-devel supervisor git redia tree net-tools sudo psmisc && yum clean all [root@docker centos]# docker build -t peter/centos:base . [root@docker centos]# docker images
#python環境 [root@docker python]# vim Dockerfile #Base image FROM peter/centos:base #Maintainer MAINTAINER Peter.Wang # Python env RUN yum install -y python-devel python-pip supervisor # Update pip RUN pip install --upgrade pip [root@docker python]# docker build -t peter/python .
#centos-ssh [root@docker centos-ssh]# vim Dockerfile # Docker for CentOS #Base image FROM centos #Maintainer MAINTAINER Peter.Wang xxx@gmail.com #EPEL ADD epel.repo /etc/yum.repos.d/ #Base pkg RUN yum install -y openssh-clients openssl-devel openssh-server wget mysql-devel supervisor git redia tree net-tools sudo psmisc && yum clean all #For SSHD RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key RUN echo "root:123456" | chpasswd [root@docker centos-ssh]# docker build -t peter/centos-ssh .
#python-ssh [root@docker python-ssh]# vim Dockerfile #Base image FROM peter/centos-ssh #Maintainer MAINTAINER Peter.Wang # Python env RUN yum install -y python-devel python-pip supervisor #supervisor是一個進程管理工具,能夠同時管理多個進程 #vim /etc/supervisord.conf #[include] #files = supervisord.d/*.ini # 咱們只須要在/etc/supervisord.d目錄下添加ini文件便可 # Update pip RUN pip install --upgrade pip [root@docker python-ssh]# docker build -t peter/python-ssh .
#shop.api [root@docker shop-api]# vim app.py from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'Hello World!' if __name__ == "__main__": app.run(host="0.0.0.0",debug=True) [root@docker shop-api]# yum install -y python-pip [root@docker shop-api]# pip install flask [root@docker shop-api]# python app.py #http://192.168.1.5:5000 [root@docker shop-api]# vim Dockerfile #Base image FROM peter/python-ssh #Maintainer MAINTAINER Peter.Wang # Python env RUN useradd -s /sbin/nologin -M www ADD app.py /opt/app.py ADD requirements.txt /opt/ ADD supervisord.conf /etc/supervisord.conf ADD app-supervisor.ini /etc/supervisord.d/ # Update pip RUN /usr/bin/pip2.7 install -r /opt/requirements.txt # Prot EXPOSE 22 5000 #CMD CMD ["/usr/bin/supervisord","-c","/etc/supervisord.conf"] [root@docker shop-api]# cp /etc/supervisord.conf . [root@docker shop-api]# vim app-supervisor.ini [program:shop-api] command=/usr/bin/python2.7 /opt/app.py process_name=%(program_name)s autostart=true user=www stdout_logfile=/tmp/app.log stderr_logfile=/tmp/app.error [program:sshd] command=/usr/sbin/sshd -D process_name=%(program_name)s autostart=true [root@docker shop-api]# vim supervisord.conf nodaemon=true ; (start in foreground if true;default false) [root@docker shop-api]# docker build -t peter/shop-api . [root@docker shop-api]# docker run --name shop-api -d -p 88:5000 -p 8022:22 peter/shop-api
mkdir -p /server/tools cd /server/tools yum install docker-compose -y # Compose是Docker的管理工具,主要用來構建基於Docker的複雜應用,Compose 經過一個配置文件來管理多個Docker容器,很是適合組合使用多個容器進行開發的場景。 wget https://github.com/vmware/harbor/releases/download/v1.2.0/harbor-offline-installer-v1.2.0.tgz tar xf harbor-online-installer-v1.2.0.tgz cd harbor vim harbor.cfg #The IP address or hostname to access admin UI and registry service. #DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients. hostname = docker.test.com # 主機名 #The protocol for accessing the UI and token/notification service, by default it is http. #It can be set to https if ssl is enabled on nginx. ui_url_protocol = http # 協議 #The password for the root user of mysql db, change this before any production use. db_password = 123456 # 數據庫root密碼 ./install.sh #在Windows作hosts解析 10.0.0.5 docker.test.com [root@lb01 harbor]# docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------------------------------ harbor-adminserver /harbor/harbor_adminserver Up harbor-db docker-entrypoint.sh mysqld Up 3306/tcp harbor-jobservice /harbor/harbor_jobservice Up harbor-log /bin/sh -c crond && rm -f ... Up 127.0.0.1:1514->514/tcp harbor-ui /harbor/harbor_ui Up nginx nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:4443->4443/tcp, 0.0.0.0:80->80/tcp registry /entrypoint.sh serve /etc/ ... Up 5000/tcp #http://docker.test.com