|
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