学习Docker过程中的一些小笔记~~~
总结:Docker是对软件和其依赖环境的标准化大包,应用之间相互隔离,共享一个OS Kernel(解决了资源浪费的问题),可以运行于很多主流的操作系统上,同时应当注意:Docker本身不是容器,Docker只是管理容器的引擎。
容器是将代码和环境的关系打包在一起的一个集合,而虚拟机是在物理层面上,分出来的一个操作系统。
多个容器可以运行在同一台物理服务器上,并共享一个操作系统的内核资源。多个虚拟机也可以运行在同一台机器上,但每个虚拟机都需要一个完整的操作系统;
Docker和传统虚拟化方式的不同之处:
从上面的两个图中便可看出:容器是在本地的操作系统层面上实现虚拟化,直接复用本地主机上的操作系统,不需要单独安装操作系统,而传统的虚拟化技术方式则需要单独安装每个虚拟机的操作系统。
Docker和虚拟机的特性对比
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘空间 | 一般为几十MB | 一般为10GB |
性能 | 接近原生 | 弱于原生 |
系统支持量 | 单机支持上千个容器 | 一般为几十个 |
操作系统 | 与宿主机共享OS | 宿主机OS上运行虚拟机OS |
Docker
在 Dockerfile
中记录了容器构建过程,可在集群中实现快速分发和快速部署docker
的安全性也更弱。 Docker
的租户 root
和宿主机 root
等同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户 root
权限和宿主机的 root
虚拟机权限是分离的,并且虚拟机利用如 Intel
的 VT-d
和 VT-x
的 ring-1
硬件隔离技术,这种隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击Docker从2013年3月20日开始发布Docker0.1;
从2017年3月开始Docker在原来的基础上分为两个分支版本:Docker CE和Docker EE。
Docker CE:社区免费版,可永久免费使用;
Docker EE:企业版,功能更全,更强调安全,需付费
Docker的官方网站:https://www.docker.com
Docker是一个管理容器的引擎,由于我使用的是CentOS7,所以我也是使用在该环境下的版本。
Docker支持CentOS6及以后的版本;
CentOS7系统可以直接通过yum进行安装;
安装前可以查看一下系统是否已经安装了Docker:
yum list installed|grep docker
若出现以下内容则表示已经安装好了:
[root@localhost ~]# yum list installed |grep docker
docker.x86_64 2:1.13.1-209.git7d71120.el7.centos
docker-client.x86_64 2:1.13.1-209.git7d71120.el7.centos
docker-common.x86_64 2:1.13.1-209.git7d71120.el7.centos
若未安装好则可以通过以下命令安装:
yum install docker -y
安装后,使用docker -version查看docker是否下载成功,
docker -version
卸载通过以下命令:
yum remove docker.x86_64 -y
yum remove docker-client.x86_64 -y
yum remove docker-common.x86_64 -y
安装之后启动Docker服务:
启动:
systemctl start docker 或者 service docker start
停止:
systemctl stop docker 或者 service docker stop
重启:
systemctl restart docker 或者 service docker restart
检查docker进程的运行状态:
systemctl status docker 或者 service docker status
查看docker进程:
[root@localhost ~]# ps -ef|grep docker
root 14218 1 0 05:09 ? 00:00:37 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json --selinux-enabled --log-driver=journald --signature-verification=false --storage-driver overlay2
root 14223 14218 0 05:09 ? 00:00:20 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc --runtime-args --systemd-cgroup=true
root 31472 22910 0 13:09 pts/1 00:00:00 grep --color=auto docker
docker info : 查看docker的系统信息
docker: 查看所有的帮助信息
docker commond -help:查看某个commond命令的帮助信息
Docker不是一个容器,而是一个管理容器的引擎。
Docker的底层运行原理:
启动Docker服务 -> 下载镜像 -> 启动该镜像得到一个容器 -> 容器里运行程序 ;
由上面docker的底层运行逻辑,按如下步骤运行第一个Docker容器:
将Docker服务启动;
下载所需要的镜像,Docker运行一个容器前需要本地存在有对应的镜像,如果镜像不存在本地,Docker会从镜像仓库下载(默认的Docker Hub 公共注册服务器中的仓库为:https://hub.docker.com)
CentOS如何下载(pull)镜像?
从docker hub官网搜索要使用的镜像,也可以在命令行或者弄个使用命令搜索要使用的镜像,比如
docker search tomcat
进行搜搜,然后下载所需要的镜像:
下载镜像:
docker pull tomcat 或者
docker pull tomcat:+ 版本号
运行镜像:
前台运行方式:
docker run tomcat
后台运行方式:
docker run tomcat -d
显示本地已有的镜像:
docker images
在列出的信息中,可以看到几个字段信息
REPOSITORY: 来自哪个仓库,比如 docker.io/tomcat
TAG: 镜像的标记,比如latest
IMAGE ID: 镜像的ID号
CREATED: 创建时间
SIZE: 镜像大小
启动下载下来的镜像得到一个容器:
docker run -d docker.io/tomcat
或者:
docker run -d bcc25679a5b4
默认情况下是前台启动,如果需要后台启动,则指定-d参数;
通过 ps -ef|grep tomcat 查看,检查tomcat 镜像是否启动容器成功;
进入容器:
docker exec -it bcc25679a5b4 bash
i: 表示交互式的,也就是保持标准输入流打开
t: 表示虚拟控制台,分配到一个虚拟控制台
退出容器: exit
从客户机上访问容器,需要有端口映射,docker容器默认采用桥接模式与宿主机通信,需要将宿主机的ip端口映射到容器的ip端口上;
停止容器:
docker stop 容器的ID/名称
启动容器:
docker run -d -p 8080:8080 docker.io/tomcat
Docker使用客户端-服务端(C/S)架构模式,使用远程API来管理和创建Docker容器。
Docker容器通过Docker镜像来创建。
镜像与容器的关系类似于面向对象编程中的类与对象的关系。容器为对象,镜像为类。
Docker有三大核心要素:
Docker的运行离不开上面几个核心组件的支持。
注意:Docker不是容器,而是管理容器的引擎。
Docker镜像就是一个只读的模板,用来创建Docker容器
例如:一个镜像可以包含一个完整的centos操作系统环境,里面仅安装了mysql或用户需要的其他应用程序。
Docker提供了一个非常简单的机制来创建镜像或更新现有的镜像,用户甚至可以直接从其他人处下载一个已经做好的镜像来直接使用。
镜像是由许多层的文件系统叠加而成的,最下面的是一个引导文件系统bootfs,第二层是一个root文件系统rootfs,root文件系统通常是某种操作系统,比如centos、Ubuntn,在root文件系统之上又有很多层文件系统,这些文件系统叠加在一起,构成了docker的镜像;
下载镜像,比如redis镜像:
docker pull redis:latest
redis是查询到的镜像名称,latest是镜像的标签tag
获取一个镜像有两种方式:
如果有官方镜像,就不用自己用Dockerfile文件构建了,除非官方没有才自己去Dockerfile文件构建;
列出已经下载的镜像:
docker images
或者
docker images redis
运行的镜像:
docker run -d redis
其中-d表示在后台运行,然后通过ps -ef|grep redis查看redis的进程
查看容器镜像的状态:
docker ps
通过docker exec -it 镜像ID bash 进入redis容器
删除容器:
docker rmi redis:版本号
注意:rmi是删除镜像 rm是删除容器
容器是从镜像创建的运行实例。它可以被启动、停止、删除。每个容器都是相互隔离的、保证安全性。可以把每个容器看作一个简易版的Linux环境,包括root用户权限、进程空间、用户空间和网络空间和运行在其中的应用程序。
Docker利用容器来运行应用,镜像是只读的,容器在启动的时候创建一层可写层作为最上层。
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态的容器重新启动
docker run -d redis
docker ps
docker ps -a
docker stop 容器的id或容器的名称
已经停止的容器,可以使用命令 docker start 来启动
docker start 容器的id或容器的名称
注意:Docker的容器非常轻量级,很多时候用户都是随时删除和新创建的容器
docker rm 容器的id或容器的名称 -f
-f:表示强制删除
删除容器的时候,容器必须是停止的状态,否则会报错;
docker exec -it 容器的id或容器的名称 bash
docker inspect + 容器的id或容器的名称 查看容器的更多信息
docker stop ${docker ps -q}
docker rm ${docker ps -aq}
docker stop ${docker ps -q} & docker rm ${docker ps -aq}
仓库是集中存放镜像文件的场所,有时候会把仓库和仓库注册服务器看作同一事物,不做严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签;
仓库分为公开的仓库和私有的仓库;
最大的公开的仓库是Docker Hub, (https://hub.docker.com)存放了数量庞大的镜像供用户下载;
用户也可以自己在本地网络内创建一个私有仓库,当用户创建了自己的镜像之后就可以用push命令将它上传到公有的或私有的仓库,这样下次在另一台机器上使用这个镜像的时候,只需要从仓库上pull下来即可;
注:Docker仓库的概念和Git类似,注册服务器也类似于Github的托管服务。
用户可以通过docker search命令来查找官方仓库中的镜像:
docker search rabbitmq
可以得到返回带有许多关键字的镜像,其中包括镜像的名字、描述、星级(用于表示该镜像的受欢迎程度)、是否为官方创建、是否自动创建;官方的镜像说明是官方项目组创建和维护的,automated资源允许用户验证镜像的来源和内容;
根据是否是官方提供,可将镜像资源分为两类:
一种类似centos这样的基础镜像,被称为基础或根镜像。这些基础镜像
由Docker公司创建、验证、支持、提供。这样的镜像往往用单个单词作为名字;
另一种类型则是tianno/centos镜像,由Docker的用户创建并维护的,往往带有用户名前缀。可以通过前缀user_name/来指定使用某个用户提供的镜像,比如tianno用户;
docker pull rabbitmq
docker pull centos
下载mysql镜像:
docker pull mysql:latest
启动mysql
docker run -p 3306:3306 -e MYSQL_DATABASE=workdb -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest
其中-e是指定环境变量
进入容器
docker exec -it 容器id bash
登录Mysql
mysql -uroot -p
修改密码
ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
授权远程登录访问:
CREATE USER 'Enzo'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT ALL PRIVILEGES ON *.* TO 'Enzo'@'%';
下载Nginx镜像
docker pull nginx
docker run -d -p 80:80 nginx
进入容器
docker exec -it 容器id
浏览器访问Nginx
http://192.168.74.132:80
Nginx部署静态网站
将linux的文件拷贝到docker容器的某个目录下
docker cp /root/test.html 容器id:/usr/share/nginx/html
下载Zookeeper
docker pull zookeeper
docker run -p 2181:2181 -d zookeeper
进入容器
docker exec -it 容器id bash
Dockerfile用于构建Docker镜像,Dockerfile文件是由一行行命令语句组成,基于这些命令即可以构建一个镜像,比如下面就是一个Dockerfile文件的样例:
FROM openjdk:8
ENV workdir=/root/Enzo_eureka/eureka-server
COPY . ${workdir}
WORKDIR ${workdir}
EXPOSE 8761
CMD ["java","-jar","eureka-server-1.0.jar"]
一般的,Dockerfile分为四个部分:
FROM
格式为 FROM或FROM :
Dockerfile文件的第一条指令必须为FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次);
MAINTAINER
格式为MAINTAINER,指定维护者信息
ENV
格式为ENV, 指定一个环境变量,会被后续RUN指令使用,并在容器运行时保持;
ADD
格式为ADD;
复制指定的到容器中的;
EXPOSE
暴露id口
格式为 EXPOSE […]
告诉Docker服务器容器暴露的端口号,供互联系统使用,在启动容器时需要通过 -p映射端口,Docker主机会自动分配一个端口转发到指定的端口;
RUN
格式为RUN
RUN指令将在当前镜像基础上执行命令,并提交为新的镜像,
当命令较长时可以用/来换行
CMD
指定启动容器时执行的命令,每个Dockerfile只能有一条CMD命令。
如果执行了多条命令,只有最后一条会被执行
如果用户启动容器时指定了运行的命令,则会覆盖掉CMD指定的命令
FROM centos:latest
MAINTAINER wkcto
ADD jdk-8u121-linux-x64.tar.gz /usr/local
ENV JAVA_HOME /usr/local/jdk1.8.0_121
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin
CMD java -version
构建镜像:
docker build -t Enzo_jdk1.8.0_121
运行镜像:
docker run -d 镜像id
定义Dockerfile文件:
FROM wkcto_jdk1.8.0_121
MAINTAINER wkcto
ADD apache-tomcat-8.5.35.tar.gz /usr/local
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.35
ENV PATH $PATH:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.35/bin/catalina.sh run
构建镜像:
docker build -t Enzo_apache-tomcat-8.5.35
运行镜像:
docker run -d 镜像id
定义Dockerfile文件:
FROM centos:centos6
MAINTAINER wkcto
RUN yum install mysql-server mysql -y
RUN /etc/init.d/mysqld start &&\
mysql -e "grant all privileges on *.* to 'root'@'%' identified by '123456' WITH GRANT OPTION;"&&\
mysql -e "grant all privileges on *.* to 'root'@'localhost' identified by '123456' WITH GRANT OPTION;"&&\
mysql -uroot -p123456 -e"show databases;"
EXPOSE 3306
CMD /usr/bin/mysqld_safe
构建镜像:
docker build -t Enzo_mysql
运行镜像:
docker run -p 3306:3306 -d 镜像id
定义Dockerfile文件:
FROM centos:latest
MAINTAINER wkcto
RUN yum install epel-release -y && yum install redis -y && yum install net-tools -y
EXPOSE 6379
CMD /usr/bin/redis-server -protected-mode no
构建镜像:
docker build -t Enzo_redis
运行镜像:
docker run -p 6379 -d 镜像id
FROM openjdk:8
ENV workdir=/root/Enzo_eureka/eureka-server
COPY . ${workdir}
WORKDIR ${workdir}
EXPOSE 8761
CMD ["java","-jar","eureka-server-1.0.jar"]
构建镜像:
docker build -t springboot-web-jar .
运行容器:
docker run -d 镜像ID号
运行Redis容器:
docker run -p 6379:6379 -d redis
运行Mysql容器:
docker run -p 3306:3306 -e MYSQL_DATABASE=workdb -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest
修改容器保存:
docker commit 容器id 镜像id
可直接通过Windows的浏览器访问,验证SpringBoot项目是否可以正常访问;
FROM Enzo-tomcat-8.5.24
MAINTAINER Enzo
ADD springboot-web-1.0.0.war /usr/local/apache-tomcat-8.5.24/webapps
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.24/bin/catalina.sh run
构建镜像:
docker build -t springboot-web-war .
与上面部署Jar程序依赖的容器环境一样
通过windows的浏览器访问,验证SpringBoot项目是否正常访问;
springboot-web-1.0.0.war -> springboot-web-1.0.0