个人简历表格模板安全优化大师
关于系统的改造探索
开篇:系统改造的调研报告
第一部分——Docker篇
第一章 Docker容器
第二章 Docker安装
第三章 构建自定义镜像
第四章 搭建镜像仓库
第五章 容器编排
第六章 容器监控
文章目录
- 关于系统的改造探索
- 第一部分——Docker篇
- 前言
- docker-compose
- networks(网络)
- volumes(数据卷)
- docker-swarm
- k3s
- 总结
前言
随着业务的发展,传统的架构已经不符合项目的要求了。双活、集群也渐渐提上了日程。。。
生产上往往不止一台机子,而部署的应用也有很多。一条条命令去敲也很麻烦,需要对进行 容器 编排,方便管理
docker-compose
首先出场的是 docker-compose,这个也是 Docker官方 提供的管理工具,不知道为什么,官方提供的往往不用
不过还是需要了解下,单机节点下还是很方便的。 docker-compose 简单来说:就是把多个 容器 的运行命令写到 YAML 文件中去,这样方便统一管理,易于共享。老样子,下边一起来体验一下
- 下载
老样子,先下载 docker-compose,这里用的是v2.24.5(根据自己需求选择)
- 安装
把下载好的文件上传至服务器,执行命令:
#重命名文件
mv docker-compose-linux-x86_64 docker-compose
#添加执行权限
chmod u+x docker-compose
#移动到系统目录
mv docker-compose /usr/bin/
#查看版本
docker-compose -v
- 验证
之前启动 镜像 都是用命令行直接启动,现在体验一下 docker-compose,看看为什么选择它。就以 一个 Springboot项目 和 Nginx 为例
Springboot项目 配置不做改动。Nginx 配置文件如下:
user nginx;
worker_processes auto;error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;events {worker_connections 1024;
}http {include /etc/nginx/mime.types;default_type application/octet-stream;log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log /var/log/nginx/access.log main;sendfile on;#tcp_nopush on;keepalive_timeout 65;#gzip on;include /etc/nginx/conf.d/*.conf;server {listen 80;server_name 192.168.233.135;location / {proxy_read_timeout 300;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://docker-demo:8080;}}}
注:其他配置大家应该都不陌生,可能会对proxy_pass http://docker-demo:8080感到疑惑,这个涉及到docker网络部分,后边会聊到
编写 YAML 文件如下:
version: '2' # 表示该 Docker-Compose 文件使用的是 Version 2 file
services:docker-demo: # 服务名称image: docker-demo:1.0container_name: docker-demo #容器名称
# build: /usr/local/docker/docker-demo # 指定 Dockerfile 所在路径ports: # 指定端口映射- "8080:8080"volumes:- /usr/local/docker/docker-demo/classes:/confignetworks:- docker-demonginx: # 服务名称image: nginxcontainer_name: nginx #容器名称ports: # 指定端口映射- "8081:80"volumes:- /usr/local/docker/nginx/logs:/var/log/nginx- /usr/local/docker/nginx/config/nginx.conf:/etc/nginx/nginx.confnetworks:- docker-demonetworks:docker-demo:driver: bridge #使用桥接创建网络
接着,进去 docker-compose 文件所在目录,执行启动命令:
#启动所有应用,-d后台启动
docker-compose -f docker-demo.yml up -d
#关闭所有应用
docker-compose -f docker-demo.yml down
#重启所有应用
docker-compose -f docker-demo.yml restart
应用起来了,疑惑也起来。下边就来看下volumes(数据卷) 和 networks(网络)
networks(网络)
玩过Vmware的应该配置过它的网络,以前该接触时,要么主机ping不通虚拟机,要么虚拟机ping不通主机,对此没少百度。现在回头再来看,Vmware的网络大致分为:
- 桥接
桥接模式下,虚拟机和宿主机都会连接到虚拟交换机上,宿主机的网卡与虚拟机的虚拟网卡通过虚拟网桥连接起来,它们的地位“平等”,同处于一个网段互不干拢,虚拟机是网络的完整参与者
-
NAT
NAT模式下,虚拟机在外部网络上没有自己的 IP 地址。相反,在宿主机上设置一个专用网络。其原理是将专用网络中虚拟机的 IP 地址转换为主机系统的 IP 地址。当虚拟机发送访问网络资源的请求时,网络资源看起来就像该请求来自主机系统。这样看来,宿主机像是虚拟机的“上级”
-
仅主机
仅主机模式下,虚拟机和主机虚拟网络适配器连接到专用以太网,虚拟机只能和主机通信,不能与外网进行通信,相当于一个封闭的局域网
跑题了~,回到 Docker,再看下 Docker 的网络:
-
Bridge
Bridge模式虽然叫Bridge,但是并不等价于Vmware的桥接,而是与NAT模式相似,docker会在宿主机创建一个docker0网卡,该网卡会与一个虚拟交换机相连,当容器以Bridge模式创建启动时,会给容器创建一个虚拟网卡,该网卡分配的IP与宿主机的docker0所在同一个局域网内 -
Host
Host模式会直接使用宿主机的网卡,容器本身并不会创建虚拟网卡,容器暴露的端口可以直接在宿主机中查到,可以当成就是在宿主机真实执行的程序。使用此模式时 -p 参数失效 -
Container
Container模式会指定一个容器的网卡为网卡,当前容器也不会创建虚拟网卡。这两个容器不能有一样的端口暴露 -
None
None模式不会给容器创建网卡,相当于一个没有网卡的机子,无法与外部通讯 -
Overlay
Overlay模式是为了在多个docker守护进程主机之间创建分布式网络,即不同机子上部署的docker可以相互通讯,该模式允许连接到它的容器(包括集群服务容器)安全地通信 -
IPvlan
IPvlan模式比较麻烦,没看懂,直接摘取官网的描述:IPvlan 是经过考验的真实网络虚拟化技术的新变化。 Linux 实现非常轻量级,因为它们不是使用传统的 Linux 桥进行隔离,而是与 Linux 以太网接口或子接口相关联,以强制网络之间的分离以及与物理网络的连接。
IPvlan提供了许多独特的功能,并为各种模式的进一步创新提供了充足的空间。这些方法的两个高级优势是,绕过 Linux 桥的积极性能影响以及移动部件较少的简单性。移除传统上位于 docker 主机 NIC 和容器接口之间的桥接器,留下由直接连接到 docker 主机接口的容器接口组成的简单设置。面向外部的服务很容易访问此结果,因为在这些场景中不需要端口映射
IPvlan L2
- Macvlan
Macvlan模式一样没看懂,官网描述:某些应用程序,尤其是遗留应用程序或监视网络流量的应用程序,期望直接连接到物理网络。在这种情况下,您可以使用Macvlan网络驱动程序为每个容器的虚拟网络接口分配一个MAC地址,使其看起来像是直接连接到物理网络的物理网络接口。在这种情况下,您需要在docker主机上指定用于 Macvlan的物理接口,以及网络的子网和网关。您甚至可以使用不同的物理网络接口隔离 Macvlan 网络
volumes(数据卷)
volumes又是个麻烦的话题。简单来说,是为了方便备份或迁移,以及共享。前文提到过,如果没有volumes(命令行的 -v 或 --mount 、Docker Compose的volumes),一旦容器挂了,数据就会丢失,类似于数据库这样的应用,怕是牢饭管饱。。。
为了避免牢饭管饱,就需要把容器内的数据映射到宿主机上边保存,这也是volumes主要作用
docker-swarm
docker-compose 还是老生常谈的问题:只能单机部署,对于集群环境,我们更需要的是对整个集群的把控。于是就有了 docker-swarm
docker-swarm 也是 Docker 官方出品的 容器编排工具 ,提供基本的 容器编排、负载均衡 和 服务发现 等功能,相较于与 k8s,docker-swarm 集成在 Docker引擎 中,不需要额外安装软件,适合较小规模的集群和较简单的应用
早期 Docker Swarm 和 k8s 处于竞争关系,最开始因为 Docker Swarm 和 Docker 无缝结合,用户更倾向于 Docker Swarm,后来 Kubernetes 崛起,并很快在容器编排领域取得了领先地位。其丰富的功能、扩展能力和强大的社区支持使得越来越多的企业选择 Kubernetes。到了 2017年,Docker 宣布在 Docker Enterprise 中集成 Kubernetes,这一举措标志着 Docker Inc. 认可了 Kubernetes 在容器编排领域的主导地位,并开始为用户提供更多选择
大概了解了 docker-swarm ,现在来一起体验下它的魅力,假定有三台已安装好 Docker环境 的机子,分别为:192.168.233.139(master节点)、192.168.233.140、192.168.233.141。如果不知道怎么安装 Docker,可以参考前面的文章
- 初始化主节点
在主节点下,执行如下命令:
docker swarm init --advertise-addr 192.168.233.139
记录下 docker swarm join --token SWMTKN-1-5u4y7wefs34fse7f5ktadmhil8ut3qnh2br9dfslte70ehx8x0-63mb5m9efjo62pax9to52yl6f 192.168.233.139:2377
,后边需要用到
- 添加从节点
在两个从节点,各自执行如下命令:
docker swarm join --token SWMTKN-1-5u4y7wefs34fse7f5ktadmhil8ut3qnh2br9dfslte70ehx8x0-63mb5m9efjo62pax9to52yl6f 192.168.233.139:2377
- 验证
在主节点下,执行如下命令进行验证:
docker node ls
可以看的出来,三台机子都已经加入集群了,并且标明了 Leader 节点
- 部署 Nginx
假定需要部署3个 Nginx,在主节点下,执行如下命令部署 Nginx :
#--publish即映射主机端口,--replicas 即部署多少个nginxdocker service create --name my-web --publish published=8080,target=80 --replicas 3 nginx
部署完成后,执行 docker service ps my-web
查看部署应用具体部署到哪里,如下:
- 扩缩容
Swarm 也支持动态扩缩容,扩容命令如下:
#把nginx个数扩展到5个
docker service scale my-web=5
缩容命令也是一样的,调整 scale 个数即可,如下:
docker service scale my-web=2
- 路由网格
我们先试用docker service ps my-web
查看下,应用的部署情况,如下:
可以看到,当前 Nginx 并没有部署在 master 节点上,现在我们用 master 节点的IP 访问看看:
可以看到,就算 master 节点没有部署 Nginx,依然可以访问的到,这个就是 Swarm 模式路由网格,当访问任何节点上的端口 8080 时,Docker 会将您的请求路由到活动容器
Swarm 除了上述这些功能,也支持 滚动更新、负载均衡、故障转移 等功能。限于篇幅,这些就由大家自己去试验了
k3s
由于这部分的内容属于 Docker 篇幅,所以这里就不过多的讨论 k8s 的相关内容,这里我们选用 k3s 来体验下就可以了
- k3s 安装
#下载minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64#安装minikube
sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64#启动
minikube start --force#启用别名
alias kubectl="minikube kubectl --"#添加提示
source <(kubectl completion bash)#验证
minikube dashboard
用虚拟机的浏览器访问url,如下:
- 部署应用
#创建服务
kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1#暴露端口
kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
- 扩缩容
#扩容到3,缩容也是同理,修改replicas数量即可
kubectl scale deployments/kubernetes-bootcamp --replicas=3#查看
kubectl get pods
这里大概体验一下,更具体的 k8s 内容会在第二部分提及,如果想继续学习的,可以参考 官网教程
总结
在 容器编排 方面,尝试了多种方案,最终还是选择了 k8s ,虽然 Docker Swarm 更简单,但是没有相应的操作界面,有操作界面的属于 Docker Cloud 的内容,一来这个是收费的内容,二来在 2018年 停止了其核心功能。k8s 虽然学习陡峭,但是提供了更完整的解决方案,社区也很完善