一:服务宿主历史
[虚拟化技术]演进
1.1 物理机时代
物理机时代:多个应用程序可能会跑在一台机器上。
1.2 虚拟机时代
虚拟机时代:一台物理机器安装多个虚拟机(VM),一个虚拟机跑多个程序。
1.3 容器时代
容器时代:一台物理机可以安装多台容器实例(container), 一个容器跑多个程序。
容器化解决了软件开发过程中一个令人非常头疼的问题,用一段对话描述:
测试人员:你这个功能有问题。
开发人员:我本地是好的啊。
二:Docker和k8s怎么用
2.0 Docker怎么用?
其实大多数人谈论 Docker 时说的是 Docker Engine,这只是一个构建和运行的容器。
在运行容器前需要编写Docker File,通过 dockerFile 生成镜像,然后才能运行 Docker 容器。
Docker File 定义了运行镜像(image)所需的所有内容,包括操作系统和软件安装位置。一般情况下都不需要从头开始编写 Docker File,在 Docker Hub 中有来自世界各地的工程师编写好的镜像,你可以基于此修改。
2.1 编排系统的需求催生 k8s
尽管Docker为容器化的应用程序提供了开放标准,但随着容器越来越多出现了一系列新问题:
- 如何协调和调度这些容器?
- 如何在升级应用程序时不会中断服务?
- 如何监视应用程序的运行状况?
- 如何批量重新启动容器里的程序?
解决这些问题需要容器编排技术,可以将众多机器抽象,对外呈现出一台超大机器。现在业界比较流行的有:k8s、Mesos、Docker Swarm。
在业务发展初期只有几个微服务,这时用 Docker 就足够了,但随着业务规模逐渐扩大,容器越来越多,运维人员的工作越来越复杂,这个时候就需要编排系统解救opers。
2.2 k8s是做什么用的?
K8s是Google研发的容器协调器,已捐赠给CNCF,现已开源。
Google 利用在容器管理多年的经验和专业知识推出了 k8s,主要用于自动化部署应用程序容器,可以支持众多容器化工具包括现在非常流行的Docker。
目前k8s 是容器编排市场的领导者,开源并公布了一系列标准化方法,主流的公有云平台都宣布支持。
2.3 Docker与k8s 难舍难分
Docker 和 k8s 在业界非常流行,都已经是事实上的标准。
Docker 是用于构建、分发、运行容器的平台和工具。
而 k8s 实际上是一个使用 Docker 容器进行编排的系统,主要围绕 pods 进行工作。Pods 是 k8s 生态中最小的调度单位,可以包含一个或多个容器。
Docker 和 k8s 是根本上不同的技术,两者可以很好的协同工作。
2.4 开发实践,灵魂追问
(1)没有 k8s 可以使用 docker 吗?
可以。实际上一些小型公司,在业务不太复杂的情况下都是直接使用 Docker。尽管 k8s 有很多好处,但是众所周知它非常复杂,业务比较简单可以放弃使用 k8s。
(2)没有 Docker 可以使用 k8s 吗?
k8s 只是一个容器编排器,没有容器拿什么编排?!
k8s 经常与 Docker 进行搭配使用,但是也可以使用其他容器,如RunC、Containerted 等。
三:常见docker 命令
//运行一个容器
docker run -it -p 8088:8088 -p 8089:8089 -p 8090:9090 -v /root/soft/docker:/root/soft/docker
命令的格式:
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
-i, --interactive=false 打开STDIN,用于控制台交互
-P: 是容器内部端口随机映射到主机的高端口。
-p: 是容器内部端口绑定到指定的主机端口。
-d, --detach=false 指定容器运行于前台还是后台
--net=bridge:使用docker daemon指定的网桥
--net=host: 容器使用主机的网络
--net=container:NAME_or_ID:使用其他容器的网路,共享IP和PORT等网络资源
--net=none:容器使用自己的网络(类似--net=bridge),但是不进行配置
-v, --volume=[] 给容器挂载存储卷,挂载到容器的某个目录
//关闭运行中的容器
docker stop 容器ID
//启动一个已经停止的容器
docker start 容器ID
//重启一个容器
docker restart 容器ID
//进入一个运行中的容器
docker attach 容器ID
//显示全部容器
docker ps -a
//显示当前运行的容器
docker ps
//查看本地镜像
docker images
//删除所有镜像,awk每行按空格或TAB分割,输出文本中的第3项,grep -v 显示不包含匹配文本的所有行
docker rmi $(docker images | grep -v RESPOSITORY | awk '{print $3}')
//构建容器
docker build -t 镜像名称 Dockerfile存放的文件夹
//建立映像文件。–rm 选项是告诉Docker,在构建完成后删除临时的Container,
//Dockerfile的每一行指令都会创建一个临时的Container,一般这些临时生成的Container是不需要的
docker build --rm=true -t loen/lamp .
//删除容器
docker rm 容器ID
//删除所有容器
docker rm $(docker ps -a)
//查看历史
docker history 镜像ID
//若是只想备份images,使用save、load即可
//若是在启动容器后(比如删除一个文件),容器内容有变化,需要备份,则使用export、import
//导出容器
docker export 容器ID > xxx.tar
//把 mynewimage 镜像保存成 tar 文件
docker save myimage | bzip2 -9 -c> /home/save.tar.bz2
//加载 myimage 镜像
bzip2 -d -c < /home/save.tar.bz2 | docker load
四:实战篇
4.1 docker 部署前端项目
4.1.1 项目打包
npm run build
运行上边命令,此时工程项目文件夹下会生成一个 Dist文件夹:
如果将该dist目录整个传到服务器上,部署成静态资源站点就能直接访问到该项目。
接下来就来构建一个这样的静态资源站点。
4.1.2 构建vue应用镜像
nginx 是一个高性能的HTTP和反向代理服务器,此处我们选用 nginx 镜像作为基础来构建我们的vue应用镜像。
docker pull nginx
docker镜像(Image)一个特殊的文件系统。Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。 镜像不包含任何动态数据,其内容在构建之后也不会被改变。docker 镜像相关操作有: 搜索镜像
docker search [REPOSITORY[:TAG]]、拉取镜像docker pull [REPOSITORY[:TAG]]、查看镜像列表docker image ls、删除镜像:docker image rm [REPOSITORY[:TAG]] / docker rmi [REPOSITORY[:TAG]]等等。docker 镜像名称由REPOSITORY和TAG组成
[REPOSITORY[:TAG]],TAG默认为latest
4.1.3 创建 nginx config配置文件
在项目根目录下创建nginx文件夹,该文件夹下新建文件nginx.conf
# nginx/nginx.conf
server {
listen 80;
listen [::]:80;
# 开启日志记录
access_log /var/log/nginx/host.access.log main;
location / {
root /usr/home/nginx/html;
index index.html index.htm;
}
location /api/ {
proxy_pass: http://localhost/
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/home/nginx/html;
}
}
该配置文件定义了首页的指向为 /usr/home/nginx/html/index.html, 所以我们可以一会把构建出来的index.html文件和相关的静态资源放到/usr/home/nginx/html目录下。
4.1.4 创建 Dockerfile 文件
# # 新建构建阶段build-stage,指定node为基础镜像,该阶段用于生成前端制品文件
# FROM node:14-alpine as build-stage
# # 指定工作目录/app用于存放前端制品,以便在COPY,RUN以及下一个构建阶段中使用。
# WORKDIR /app
# # 复制package.json、package-lock.json、yarn.lock到工作目录里,COPY最后一个参数dest如果是相对路径,则会以工作目录有作为基准,复制到WORKDIR/<dest>里
# COPY package*.json yarn.lock ./
# # 下载依赖
# RUN yarn install
# COPY . .
# # 生成制品
# RUN yarn build
# 新建构建阶段deploy-stage,指定nginx为基础镜像,该阶段用于配置和运行nginx
FROM nginx:latest
# 把build-stage阶段中的前端制品和nginx.conf配置文件复制到nginx的指定路径里
# 这样子就可以设置nginx的配置文件,而配置文件中的默认匹配路径是/home/nginx/html,也就是存放前端制品的路径
COPY dist/ /home/share/nginx/html
COPY nginx/nginx.conf /home/nginx/conf.d/default.conf
# 指定容器在运行过程时监听80端口
EXPOSE 80
# 指定在容器开启运行时,通过运行以下命令行指令开启nignx
CMD ["nginx", "-g", "daemon off;"]
自定义构建镜像的时候基于Dockerfile来构建。
FROM nginx命令的意思该镜像是基于 nginx:latest 镜像而构建的。
COPY dist/ /home/share/nginx/html命令的意思是将项目根目录下dist文件夹下的所有文件复制到镜像中 /home/share/nginx/html 目录下。
COPY ginx/nginx.conf /home/nginx/conf.d/default.conf命令的意思是将nginx目录下的nginx.conf 复制到 /home/nginx/conf.d/default.conf,用本地的 nginx.conf 配置来替换nginx镜像里的默认配置
4.1.5 基于DockerFile 构建Vue镜像
运行命令 (注意不要少了最后的“.”)
docker build -t vuenginxcontainer .
-t 是给镜像命名,. 是基于当前目录的DockerFile来构建镜像
查看本地镜像命令:
docker image ls | grep vuenginxcontainer
到此时我们的 vue 应用镜像 vuenginxcontainer 已经成功创建。接下来,我们基于该镜像启动一个docker容器。
4.1.6 启动 vue app 容器
Docker 容器Container: 镜像运行时的实体。镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等 。
基于 vuenginxcontainer 镜像启动容器,运行命令:
docker run \
-p 6000:80 \
-d --name vueApp \
vuenginxcontainer
docker run基于镜像启动一个容器-p 6000:80端口映射,将宿主的6000端口映射到容器的80端口-d后台方式运行--name容器名 查看 docker 进程
docker ps
可以发现名为 vueApp的容器已经运行起来。此时访问 [http://localhost:6000] 应该就能访问到该vue应用.