kubernetes+Istio+CICD+Kubevirt
kubernetes部分
Kubernetes基础
本互动教程介绍了Kubernetes群集编排系统的基础知识。每个模块都包含Kubernetes的主要功能、概念的一些背景介绍。使用本教程,你可以了解:
• 在集群上部署容器化应用
• 集群规模化部署
• 更新容器化应用的版本
• 调试容器化应用
这些教程使用Katacoda在浏览器中运行虚拟终端,虚拟终端运行Minikube,它可在任何环境任何地方小规模的部署Kubernetes,且不需要安装任何软件或配置任何东西,每个互动教程都在自己浏览器中运行。
Kubernetes 特点
• 可移植: 支持公有云,私有云,混合云,多重云(multi-cloud)
• 可扩展: 模块化, 插件化, 可挂载, 可组合
• 自动化: 自动部署,自动重启,自动复制,自动伸缩/扩展
容器优势总结:
• 快速创建/部署应用:与VM虚拟机相比,容器镜像的创建更加容易。
• 持续开发、集成和部署:提供可靠且频繁的容器镜像构建/部署,并使用快速和简单的回滚(由于镜像不可变性)。
• 开发和运行相分离:在build或者release阶段创建容器镜像,使得应用和基础设施解耦。
• 开发,测试和生产环境一致性:在本地或外网(生产环境)运行的一致性。
• 云平台或其他操作系统:可以在 Ubuntu、RHEL、 CoreOS、on-prem、Google Container Engine或其它任何环境中运行。
• Loosely coupled,分布式,弹性,微服务化:应用程序分为更小的、独立的部件,可以动态部署和管理。
• 资源隔离
• 资源利用:更高效
使用Kubernetes能做什么?
可以在物理或虚拟机的Kubernetes集群上运行容器化应用,Kubernetes能提供一个以“容器为中心的基础架构”,满足在生产环境中运行应用的一些常见需求,如:
• 多个进程(作为容器运行)协同工作。 (Pod)
• 存储系统挂载
• Distributing secrets
• 应用健康检测
• 应用实例的复制
• Pod自动伸缩/扩展
• Naming and discovering
• 负载均衡
• 滚动更新
• 资源监控
• 日志访问
• 调试应用程序
• 提供认证和授权
k8s部署
使用kubeeasy进行部署k8s集群
github地址:https://github.com/kongyu666/kubeeasy
gitee地址:https://gitee.com/iskongyu/kubeeasy
版本
版本:kubeeasy-v1.3.2
更新说明:
1. 新增安装软件包并发执行任务
2. 新增私有容器registry仓库,用于集群拉取镜像
3. 修改容器镜像的操作
4. 新增系统指标检测(CPU Memory Disk)
5. 新增集群优化系统配置
6. 新增集群使用命令输出
7. 优化部分内容
要求
OS:centos 7.9 x64
CPU:2C及以上
MEM:4G及以上
认证:集群节点需统一认证,需使用同一用户名和密码
运行:在预设的master节点执行
功能
• 支持升级集群内核,升级后内核版本为:5.17.9
• 支持离线部署普通的k8s集群,k8s版本为:v1.22.1
• 支持离线部署高可用k8s集群,k8s版本为:v1.22.1
• K8S HA集群使用云原生的kube-vip,其自带VIP和负载均衡
• K8S集群默认安装图形化管理工具kuboard-v2
• K8S集群默认安装local-hostpath存储类
• K8S证书100年,且开启了自动轮询
• 内置容器镜像的功能:pull、push、save、load
集群模式选择
以下提供了两种K8S集群方案,根据实际情况选择一种方案即可
高可用集群模式主机列表
主机名 | IP 地址 |
角色 |
---|---|---|
192.168.1.201 |
k8s-maste-noder01 |
master | etcd | worker | kube-vip |
192.168.1.202 |
k8s-master-node02 |
master | etcd | worker | kube-vip |
192.168.1.203 |
k8s-master-node03 |
master | etcd | worker | kube-vip |
192.168.1.204 |
k8s-worker-node1 |
worker |
192.168.1.205 |
k8s-worker-node3 |
worker |
192.168.1.250 |
/ |
虚拟 IP 地址 |
普通集群模式主机列表
主机名 | IP 地址 |
角色 |
---|---|---|
192.168.1.201 |
k8s-maste-noder01 |
master | etcd | worker |
192.168.1.202 |
k8s-worker-node1 |
worker |
192.168.1.203 |
k8s-worker-node2 |
worker |
安装方式只有离线版 ,还有其他功能,在其他功能 里面可以查看
离线安装方式
注意:离线部署方式的主机必须配置网关
1.1 安装kubeeasy
将kubeeasy文件上传至预设的master节点/root目录,然后赋予执行权限并移动到/usr/bin目录下
mv kubeeasy-v1.3.2.sh /usr/bin/kubeeasy && chmod +x /usr/bin/kubeeasy
1.2 集群安装依赖包
使用kubeeasy在集群中安装软件包,包含远程连接sshpass等软件包
kubeeasy install depend \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000 \
--offline-file ./centos-7-rpms.tar.gz
[root@master ~]# kubeeasy install dependencies \
--host 192.168.0.10,192.168.0.11,192.168.0.12 \
--user root \
--password 000000 \
--offline-file /opt/dependencies/base-rpms.tar.gz
1.3 基础ssh配置
使用kubeeasy在集群中创建ssh免秘钥,其中优化的ssh的连接以及配置了集群的免秘钥登录等
1. 集群连通性检测-ssh
kubeeasy check ssh \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000
1. 集群免秘钥设置
kubeeasy create ssh-keygen \
--master 192.168.1.201 \
--worker 192.168.1.202,192.168.1.203 \
--user root \
--password 000000
1.4 磁盘挂载
使用kubeeasy在集群中挂载数据盘,将其挂载到/data目录,后续的数据存储路径默认都是在/data目录下。(如果没有磁盘可以忽略此操作)
1. 磁盘挂载(集群磁盘名相同时)
kubeeasy create mount-disk \
--host 192.168.1.201-192.168.1.203 \
--disk /dev/sdb \
--mount-dir /data \
--user root \
--password 000000
1. 磁盘挂载(集群磁盘名不同时只能按顺序操作)
kubeeasy create mount-disk \
--host 192.168.1.201 \
--disk /dev/sdb \
--mount-dir /data \
--user root \
--password 000000
1.5 集群升级系统内核
使用kubeeasy升级集群的内核,将其3.10的内核升级为5.14(建议升级内核)。脚本执行完后,会自动重启主机,以生效系统内核。
1. 升级集群内核为5.x
kubeeasy install upgrade-kernel \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000 \
--offline-file ./kernel-rpms-v5.17.9.tar.gz
1.6 部署K8S集群
使用kubeeasy部署K8S集群,以下分为普通集群和高可用集群的安装方式,根据实际情况选择一种方案部署。安装后的K8S的版本为v1.21.3,使用docker作为容器运行时,网络组件使用calico网络,默认还安装kuboard图形化管理器和K8S存储类(openebs-hostpath),K8S的证书有效期为100年,且开启了证书轮换
如需更改K8S的Pod网段,修改--pod-cidr参数相应的值
1. 安装k8s集群
kubeeasy install kubernetes \
--master 192.168.1.201 \
--worker 192.168.1.202,192.168.1.203 \
--user root \
--password 000000 \
--version 1.21.3 \
--pod-cidr 10.244.0.0/16 \
--offline-file ./kubeeasy-v1.3.2.tar.gz
[root@master ~]# kubeeasy install kubernetes \
--master 192.168.0.10 \
--worker 192.168.0.11,192.168.0.12 \
--user root \
--password 000000 \
--version 1.22.1 \
--offline-file /opt/kubernetes.tar.gz
1. 安装高可用k8s集群(master节点个数必须大于等于3)
kubeeasy install kubernetes \
--master 192.168.1.201,192.168.1.202,192.168.1.203 \
--worker 192.168.1.204 \
--user root \
--password 000000 \
--version 1.21.3 \
--virtual-ip 192.168.1.250 \
--pod-cidr 10.244.0.0/16 \
--offline-file ./kubeeasy-v1.3.2.tar.gz
其他功能
重置K8S节点
使用kubeeasy将集群重置(意思就是删除所有相关软件,恢复一个纯净的系统)
1. 重置正常的K8S集群(会重置整个集群)
kubeeasy reset \
--user root \
--password 000000
1. 强制重置指定的节点(如果节点不正常可以选择强制重置节点)
kubeeasy reset --force \
--master 192.168.1.201 \
--worker 192.168.1.202 \
--user root \
--password 000000
增加K8S节点
使用kubeeasy将新的节点加入K8S集群中
1. 离线增加K8S节点
增加master节点只适用于高可用集群的模式
从普通的K8S集群转换为高可用的K8S集群点击 这里
# 需要先安装依赖包
kubeeasy install depend \
--host 192.168.1.204,192.168.1.205 \
--user root \
--password 000000 \
--offline-file ./centos-7-rpms.tar.gz
# 加入K8S集群
kubeeasy add \
--worker 192.168.1.204,192.168.1.205
--user root \
--password 000000 \
--offline-file ./kubeeasy-v1.3.2.tar.gz
删除K8S节点
使用kubeeasy将节点从K8S集群中删除
1. 删除K8S节点
删除操作会重置节点,包括删除K8S服务、docker数据等清空操作。
kubeeasy delete \
--worker 192.168.1.202,192.168.1.203
--user root \
--password 000000
移除K8S节点
使用kubeeasy将节点从K8S集群中移除
1. 移除K8S节点
移除操作会不会重置节点,只是从K8S集群中移除,并不会删除docker的数据。
kubeeasy remove \
--worker 192.168.1.202,192.168.1.203
--user root \
--password 000000
集群分发并读取容器镜像
使用kubeeasy将容器镜像离线包分发到指定节点并读取,如test-images.tar.gz。
1. 分发现有的容器镜像并读取
kubeeasy images load \
--host 192.168.1.201,192.168.1.201,192.168.1.203 \
--user root \
--password 000000 \
--offline-file test-images.tar.gz
容器镜像
使用kubeeasy将容器列表文件的镜像保存到指定目录、也可以将其上传到镜像仓库中,但前提是您需要先登录镜像仓库。
images-list.txt 文件命名规范:
test :表示一个镜像包集,下方区域是镜像列表,保存后以test命名
1. 保存镜像离线包
kubeeasy images save \
--images-file images-list.txt \
--images-dir ./images
1. 推送镜像到仓库
docker login dockerhub.kubeeasy.local:5000 -u admin -p admin
kubeeasy images push \
--images-file images-list.txt \
--images-registry dockerhub.kubeeasy.local:5000/kongyu
其他
集群优化系统配置
## 依赖于sshpass命令,需要先安装此命令
rpm -ivh https://mirrors.aliyun.com/centos/7/extras/x86_64/Packages/sshpass-1.06-2.el7.x86_64.rpm
kubeeasy install precondition \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000
集群使用命令
kubeeasy get command \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000 \
--cmd "hostname"
集群免秘钥设置
kubeeasy create ssh-keygen \
--master 192.168.1.201 \
--worker 192.168.1.202,192.168.1.203 \
--user root \
--password 000000
集群时间同步设置
kubeeasy create time \
--master 192.168.1.201 \
--worker 192.168.1.202,192.168.1.203 \
--user root \
--password 000000
集群系统指标检测(CPU Memory Disk)
kubeeasy check system \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000
集群连通性检测-ssh
kubeeasy check ssh \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000
集群连通性检测-ping
kubeeasy check ping \
--host 192.168.1.201-192.168.1.203
修改集群root密码
kubeeasy create password \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000 \
--new-password 123456
清除历史命令
kubeeasy set history \
--host 192.168.1.201-192.168.1.203 \
--user root \
--password 000000
kubernetes集群部署其他服务
使用kubeeasy部署Kubevirt
[root@k8s-master-node1 ~]# kubeeasy add --virt kubevirt
使用kubeeasy部署Istio
[root@k8s-master-node1 ~]# kubeeasy add --istio istio
使用kubeeasy部署Harbor
[root@k8s-master-node1 ~]# kubeeasy add --registry harbor
worker-node1节点容器部署Mall项目
Mall 电商应用系统说明
模块 |
|
mall-monitor |
监控中心 |
mall-gateway |
微服务网关 |
mall-auth |
认证中心 |
mall-admin |
商城后台服务 |
mall-portal |
商城前台服务 |
前期准备
[root@k8s-master-node1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master-node1 Ready control-plane,master,worker 9h v1.22.1
k8s-worker-node1 Ready worker 9h v1.22.1
k8s-worker-node2 Ready worker 9h v1.22.1
[root@k8s-master-node1 ~]# kubectl cluster-info
Kubernetes control plane is running at https://apiserver.cluster.local:6443
CoreDNS is running at https://apiserver.cluster.local:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
[root@k8s-worker-node1 ~]# docker -v
Docker version 20.10.14, build a224086
[root@k8s-worker-node1 ~]# docker-compose -v
Docker Compose version v2.2.1
[root@k8s-worker-node1 ~]# tar -xvf mall-swarm.tar
[root@k8s-worker-node1 mall-swarm]# scp -r mall-repo 192.168.0.10:/opt/
[root@k8s-worker-node1 mall-swarm]# cat ftp.repo
[CentOS]
name=CentOS
baseurl=ftp://192.168.0.10/centos
gpgcheck=0
enabled=1
[mall]
name=mall
name=mall
baseurl=ftp://192.168.0.10/mall-repo
gpgcheck=0
enabled=1
Dockerfile容器化部署Mall
1.容器化部署数据库
[root@k8s-worker-node1 mall-swarm]# cat Dockerfile-mysql
FROM centos:centos7.5.1804
MAINTAINER JW
RUN rm -rf /etc/yum.repos.d/*
ADD ftp.repo /etc/yum.repos.d/
ADD init.sh mall.sql /opt/
RUN yum -y install mariadb-server \
&& bash /opt/init.sh
ENV LC_ALL en_US.UTF-8
EXPOSE 3306
CMD ["mysqld_safe","--user=root"]
[root@k8s-worker-node1 mall-swarm]# cat init.sh
#!/bin/bash
mysql_install_db --user=root
mysqld_safe --user=root &
sleep 5
mysqladmin -u root password 'root'
mysql -uroot -proot -e "grant all privileges on *.* to reader@'%' identified by '123456';"
mysql -uroot -proot -e "set names utf8; create database mall character set utf8; use mall; source /opt/mall.sql;"
[root@k8s-worker-node1 mall-swarm]# docker build -t mall-mysql -f Dockerfile-mysql .
2.容器化部署redis
[root@k8s-worker-node1 mall-swarm]# cat Dockerfile-redis
FROM centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rf /etc/yum.repos.d/*
ADD ftp.repo /etc/yum.repos.d/
RUN yum -y install redis \
&& sed -i "s/bind 127.0.0.1/bind 0.0.0.0/g" /etc/redis.conf \
&& sed -i "s/protected-mode yes/protected-mode no/g" /etc/redis.conf
EXPOSE 6379
CMD ["redis-server","/etc/redis.conf"]
[root@k8s-worker-node1 mall-swarm]# docker build -t mall-redis -f Dockerfile-redis .
3.容器化部署nacos注册中心
[root@k8s-worker-node1 mall-swarm]# cat Dockerfile-nacos
FROM centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rf /etc/yum.repos.d/*
ADD ftp.repo /etc/yum.repos.d/
ADD jdk-8u121-linux-x64.tar.gz nacos-server-1.1.0.tar.gz /usr/local/bin/
ADD start.sh /root/
RUN chmod +x /root/start.sh
ENV JAVA_HOME /usr/local/bin/jdk1.8.0_121
EXPOSE 8848
CMD ["bin/bash","/root/start.sh"]
[root@k8s-worker-node1 mall-swarm]# cat start.sh
#!/bin/bash
/usr/local/bin/nacos/bin/startup.sh -m standalone && tail -f /usr/local/bin/nacos/logs/start.out
[root@k8s-worker-node1 mall-swarm]# docker build -t mall-nacos -f Dockerfile-nacos .
4.容器化部署web前端项目
[root@k8s-worker-node1 mall-swarm]# tar -zxvf mall-admin-web.tar.gz
[root@k8s-worker-node1 mall-admin-web]# cat config/prod.env.js
'use strict'
module.exports = {
NODE_ENV: '"production"',
BASE_API: '"http://192.168.0.11:8201/mall-admin"'
}
[root@k8s-worker-node1 mall-swarm]# tar -zxvf node-v6.17.1-linux-x64.tar.gz -C /usr/local/
[root@k8s-worker-node1 mall-swarm]# ln -s /usr/local/node-v6.17.1-linux-x64/bin/node /usr/local/bin/node
[root@k8s-worker-node1 mall-swarm]# ln -s /usr/local/node-v6.17.1-linux-x64/bin/npm /usr/local/bin/npm
[root@k8s-worker-node1 mall-swarm]# ll /usr/local/bin/
total 24068
-rwxr-xr-x 1 root root 24645632 Jul 30 20:26 docker-compose
lrwxrwxrwx 1 root root 42 Jul 30 20:51 node -> /usr/local/node-v6.17.1-linux-x64/bin/node
lrwxrwxrwx 1 root root 41 Jul 30 20:51 npm -> /usr/local/node-v6.17.1-linux-x64/bin/npms
[root@k8s-worker-node1 mall-admin-web]# npm -v
3.10.10
[root@k8s-worker-node1 mall-admin-web]# node -v
v6.17.1
[root@k8s-worker-node1 mall-admin-web]# npm run build
[root@k8s-worker-node1 mall-admin-web]# mv dist ..
[root@k8s-worker-node1 mall-swarm]# docker build -t mall-nginx -f Dockerfile-nginx .
5.docker-compose编排Mall商城
[root@k8s-worker-node1 images]# docker load < mall_mall-admin_1.0-SNAPSHOT.tar
[root@k8s-worker-node1 images]# docker load < mall_mall-auth_1.0-SNAPSHOT.tar
[root@k8s-worker-node1 images]# docker load < mall_mall-gateway_1.0-SNAPSHOT.tar
[root@k8s-worker-node1 mall-swarm]# cat docker-compose.yaml
version: '3'
services:
chinaskillmall-admin:
container_name: chinaskillmall-admin
image: mall/mall-admin:1.0-SNAPSHOT
ports:
- 8080:8080
chinaskillmall-auth:
container_name: chinaskillmall-auth
image: mall/mall-auth:1.0-SNAPSHOT
ports:
- 8401:8401
chinaskillmall-getway:
container_name: chinaskillmall-getway
image: mall/mall-gateway:1.0-SNAPSHOT
ports:
- 8201:8201
db:
container_name: chinaskillmall-mysql
image: mall-mysql:latest
nacos-registry:
container_name: chinaskillmall-nacos
image: mall-nacos:latest
ports:
- 8848:8848
nginx:
container_name: chinaskillmall-nginx
image: mall-nginx:latest
ports:
- 8888:80
redis:
container_name: chinaskillmall-redis
image: mall-redis:latest
ports:
- 6379:6379
[root@k8s-worker-node1 mall-swarm]# docker-compose up
[root@k8s-worker-node1 mall-swarm]# docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
chinaskillmall-admin "java -jar -Dspring.…" chinaskillmall-admin running 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp
chinaskillmall-auth "java -jar -Dspring.…" chinaskillmall-auth running 0.0.0.0:8401->8401/tcp, :::8401->8401/tcp
chinaskillmall-getway "java -jar -Dspring.…" chinaskillmall-getway running 0.0.0.0:8201->8201/tcp, :::8201->8201/tcp
chinaskillmall-mysql "mysqld_safe --user=…" db running 3306/tcp
chinaskillmall-nacos "bin/bash /root/star…" nacos-registry running 0.0.0.0:8848->8848/tcp, :::8848->8848/tcp
chinaskillmall-nginx "nginx -g 'daemon of…" nginx running 0.0.0.0:8888->80/tcp, :::8888->80/tcp
chinaskillmall-redis "redis-server /etc/r…" redis running 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp
云原生部分
技术的变革,一定是思想先行,云原生是一种构建和运行应用程序的方法,是一套技术体系和方法论。云原生(CloudNative)是一个组合词,Cloud+Native。Cloud表示应用程序位于云中,而不是传统的数据中心;Native表示应用程序从设计之初即考虑到云的环境,原生为云而设计,在云上以最佳姿势运行,充分利用和发挥云平台的弹性+分布式优势。
总而言之,符合云原生架构的应用程序应该是:采用开源堆栈(K8S+Docker)进行容器化,基于微服务架构提高灵活性和可维护性,借助敏捷方法、DevOps支持持续迭代和运维自动化,利用云平台设施实现弹性伸缩、动态调度、优化资源利用率。**
云元素的四要素
微服务:几乎每个云原生的定义都包含微服务,跟微服务相对的是单体应用,微服务有理论基础,那就是康威定律,指导服务怎么切分,很玄乎,凡是能称为理论定律的都简单明白不了,不然就忒没b格,大概意思是组织架构决定产品形态,不知道跟马克思的生产关系影响生产力有无关系。
微服务架构的好处就是按function切了之后,服务解耦,内聚更强,变更更易;另一个划分服务的技巧据说是依据DDD来搞。
容器化:Docker是应用最为广泛的容器引擎,在思科谷歌等公司的基础设施中大量使用,是基于LXC技术搞的,容器化为微服务提供实施保障,起到应用隔离作用,K8S是容器编排系统,用于容器管理,容器间的负载均衡,谷歌搞的,Docker和K8S都采用Go编写,都是好东西。
DevOps:这是个组合词,Dev+Ops,就是开发和运维合体,不像开发和产品,经常刀刃相见,实际上DevOps应该还包括测试,DevOps是一个敏捷思维,是一个沟通文化,也是组织形式,为云原生提供持续交付能力。
持续交付:持续交付是不误时开发,不停机更新,小步快跑,反传统瀑布式开发模型,这要求开发版本和稳定版本并存,其实需要很多流程和工具支撑。
云原生景观图
CICD持续构建gpmall项目
worker-node2节点
前期准备
[root@k8s-master-node1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master-node1 Ready control-plane,master,worker 22h v1.22.1
k8s-worker-node1 Ready worker 22h v1.22.1
k8s-worker-node2 Ready worker 22h v1.22.1
[root@k8s-worker-node2 ~]# docker -v
Docker version 20.10.14, build a224086
[root@k8s-worker-node2 ~]# docker-compose -v
Docker Compose version v2.2.1
[root@k8s-master-node1 ~]# kubectl cluster-info
Kubernetes control plane is running at https://apiserver.cluster.local:6443
CoreDNS is running at https://apiserver.cluster.local:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
[root@k8s-worker-node2 ~]# tar -zxvf gpmall-single.tar.gz
[root@k8s-worker-node2 gpmall-single]# scp -r gpmall-repo 192.168.0.10:/opt/
[root@k8s-worker-node2 gpmall-single]# mkdir kafka
[root@k8s-worker-node2 gpmall-single]# mkdir zookeeper
[root@k8s-worker-node2 gpmall-single]# mkdir mariadb
[root@k8s-worker-node2 gpmall-single]# mkdir nginx
[root@k8s-worker-node2 gpmall-single]# mkdir jenkins
[root@k8s-worker-node2 gpmall-single]# mkdir gitlab
[root@k8s-worker-node2 gpmall-single]# cat ftp.repo
[CentOS]
name=CentOS
baseurl=ftp://192.168.0.10/centos
gpgcheck=0
enabled=1
[gpmall]
name=gpmall
baseurl=ftp://192.168.0.10/gpmall-repo
gpgcheck=0
enabled=1
CICD构建Gpmall
1.部署jekins
[root@k8s-worker-node2 gpmall]# cat jenkins/docker-compose.yaml
version: "3"
services:
jenkins:
image: jenkins/jenkins:2.262-centos
container_name: jenkins
ports:
- 8080:8080
expose:
- 8080
- 50000
user: root
privileged: true
volumes:
- /home/jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
- /usr/bin/kubectl:/usr/bin/kubectl
- /root/.kube:/root/.kube
创建gpmall用户
系统管理→管理用户
设置安全配置
2.部署gitlab
[root@k8s-worker-node2 gpmall]# ssh-keygen -t rsa
[root@k8s-worker-node2 gpmall]# ll ~/.ssh/
total 12
-rw------- 1 root root 1679 Jul 31 09:32 id_rsa
-rw-r--r-- 1 root root 403 Jul 31 09:32 id_rsa.pub
-rw-r--r-- 1 root root 174 Jul 31 09:08 known_hosts
[root@k8s-worker-node2 gitlab]# cat docker-compose.yaml
version: "3"
services:
gitlab:
image: gitlab/gitlab-ce:12.9.2-ce.0
container_name: gitlab
restart: always
ports:
- 81:80
- 443:443
- "1022:22"
hostname: 192.168.100.10
environment:
TZ: "Asia/Shanghai"
volumes:
- /srv/gitlab/config:/etc/gitlab
- /srv/gitlab/logs:/var/log/gitlab
- /srv/gitlab/gitlab/data:/var/opt/gitlab
[root@k8s-worker-node2 gitlab]# docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
gitlab "/assets/wrapper" gitlab running (starting) 0.0.0.0:1022->22/tcp, 0.0.0.0:81->80/tcp, 0.0.0.0:443->443/tcp, :::1022->22/tcp, :::81->80/tcp, :::443->443/tcp
创建gpmall项目
SSH密钥
[root@k8s-worker-node2 gpmall]# ssh -T git@192.168.0.12 -p 1022
Warning: Permanently added '[192.168.0.12]:1022' (ECDSA) to the list of known hosts.
Welcome to GitLab, @root!
3.配置jenkins与gitlab的连接
gitlab
Jenkins
系统管理→配置
4.编写Dockerfile及相关配置
Dockerfile部分
[root@k8s-worker-node2 gpmall]# ll kafka/
total 92932
-rw-r--r-- 1 root root 463 Jul 31 10:06 Dockerfile
-rw-r--r-- 1 root root 158 Jul 31 09:13 ftp.repo
-rw-r--r-- 1 root root 57471165 Nov 13 2020 kafka_2.11-1.1.1.tgz
-rw-r--r-- 1 root root 37676320 Nov 13 2020 zookeeper-3.4.14.tar.gz
[root@k8s-worker-node2 gpmall]# cat kafka/Dockerfile
FROM centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rf /etc/yum.repos.d/*
ADD ftp.repo /etc/yum.repos.d/
ADD kafka_2.11-1.1.1.tgz zookeeper-3.4.14.tar.gz /opt/
RUN yum -y install java-1.8.0-openjdk* \
&& mv /opt/zookeeper-3.4.14/conf/zoo_sample.cfg /opt/zookeeper-3.4.14/conf/zoo.cfg
EXPOSE 9092
CMD ["sh","-c","/opt/zookeeper-3.4.14/bin/zkServer.sh start && /opt/kafka_2.11-1.1.1/bin/kafka-server-start.sh /opt/kafka_2.11-1.1.1/config/server.properties"]
[root@k8s-worker-node2 gpmall]# ll mariadb/
total 72
-rw-r--r-- 1 root root 267 Jul 31 10:06 Dockerfile
-rw-r--r-- 1 root root 158 Jul 31 09:13 ftp.repo
-rw-r--r-- 1 root root 59239 Nov 13 2020 gpmall.sql
-rw-r--r-- 1 root root 327 Jul 31 10:07 init.sh
[root@k8s-worker-node2 gpmall]# cat mariadb/Dockerfile
FROM centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rf /etc/yum.repos.d/*
ADD ftp.repo /etc/yum.repos.d/
ADD gpmall.sql init.sh /opt/
RUN yum -y install mariadb-server \
&& bash /opt/init.sh
ENV LC_ALL en_US.UTF-8
EXPOSE 3306
CMD ["mysqld_safe","--user=root"]
[root@k8s-worker-node2 gpmall]# cat mariadb/init.sh
#!/bin/bash
mysql_install_db --user=root
mysqld_safe --user=root &
sleep 5
mysqladmin -u root password '123456'
mysql -uroot -p123456 -e "grant all privileges on *.* to root@'%' identified by '123456';"
mysql -uroot -p123456 -e "set names utf8; create database gpmall character set utf8; use gpmall; source /opt/gpmall.sql;"
[root@k8s-worker-node2 gpmall]# ll nginx/
total 199332
drwxr-xr-x 3 root root 38 Nov 13 2020 dist
-rw-r--r-- 1 root root 653 Jul 31 10:08 Dockerfile
-rw-r--r-- 1 root root 158 Jul 31 09:14 ftp.repo
-rw-r--r-- 1 root root 47765224 Nov 13 2020 gpmall-shopping-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root 39005468 Nov 13 2020 gpmall-user-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root 252 Jul 31 10:09 setup.sh
-rw-r--r-- 1 root root 54936064 Nov 13 2020 shopping-provider-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root 62386947 Nov 13 2020 user-provider-0.0.1-SNAPSHOT.jar
[root@k8s-worker-node2 gpmall]# cat nginx/Dockerfile
FROM centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rf /etc/yum.repos.d/*
ADD ftp.repo /etc/yum.repos.d/
ADD *.jar setup.sh /opt/
RUN yum -y install nginx java-1.8.0-openjdk* \
&& sed -i "1a location /shopping { proxy_pass http://127.0.0.1:8081; }" /etc/nginx/conf.d/default.conf \
&& sed -i "2a location /user { proxy_pass http://127.0.0.1:8082; }" /etc/nginx/conf.d/default.conf \
&& sed -i "3a location /cashier { proxy_pass http://127.0.0.1:8083; }" /etc/nginx/conf.d/default.conf \
&& chmod +x /opt/setup.sh \
&& rm -rf /usr/share/nginx/html/*
ADD dist /usr/share/nginx/html/
EXPOSE 80 8081 8082 8083 443
CMD ["nginx","-g","daemon off;"]
[root@k8s-worker-node2 gpmall]# cat nginx/setup.sh
#!/bin/bash
java -jar /root/shopping-provider-0.0.1-SNAPSHOT.jar &
sleep 5
java -jar /root/user-provider-0.0.1-SNAPSHOT.jar &
sleep 5
java -jar /root/gpmall-shopping-0.0.1-SNAPSHOT.jar &
sleep 5
java -jar /root/gpmall-user-0.0.1-SNAPSHOT.jar &
sleep 5
[root@k8s-worker-node2 gpmall]# ll redis/
total 4
-rw-r--r-- 1 root root 321 Jul 31 10:07 Dockerfile
[root@k8s-worker-node2 gpmall]# cat redis/Dockerfile
FROM centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rf /etc/yum.repos.d/*
ADD ftp.repo /etc/yum.repos.d/
RUN yum -y install redis \
&& sed -i "s/bind 127.0.0.1/bind 0.0.0.0/g" /etc/redis.conf \
&& sed -i "s/protected-mode yes/protected-mode no/g" /etc/redis.conf
EXPOSE 6379
CMD ["redis-server","/etc/redis.conf"]
[root@k8s-worker-node2 gpmall]# ll zookeeper/
total 36804
-rw-r--r-- 1 root root 367 Jul 31 10:06 Dockerfile
-rw-r--r-- 1 root root 158 Jul 31 09:14 ftp.repo
-rw-r--r-- 1 root root 37676320 Jul 31 09:15 zookeeper-3.4.14.tar.gz
[root@k8s-worker-node2 gpmall]# cat zookeeper/Dockerfile
FROM centos:centos7.5.1804
MAINTAINER Chinaskill
RUN rm -rf /etc/yum.repos.d/*
ADD ftp.repo /etc/yum.repos.d/
ADD zookeeper-3.4.14.tar.gz /opt/
RUN yum -y install java-1.8.0-openjdk* \
&& mv /opt/zookeeper-3.4.14/conf/zoo_sample.cfg /opt/zookeeper-3.4.14/conf/zoo.cfg
EXPOSE 2181
CMD ["sh","-c","/opt/zookeeper-3.4.14/bin/zkServer.sh start && tail -f /etc/shadow"]
#gpmall.yaml
[root@k8s-worker-node2 gpmall]# cat gpmall.yaml
apiVersion: v1
kind: Pod
metadata:
name: gpmall
labels:
app: gpmall
spec:
hostAliases:
- ip: 127.0.0.1
hostnames:
- "zookeeper.mall"
- "kafka.mall"
- "mysql.mall"
- "redis.mall"
containers:
- name: redis
image: chinaskill-redis:v1.1
ports:
- containerPort: 6379
- name: mariadb
image: chinaskill-mariadb:v1.1
ports:
- containerPort: 3306
- name: zookeeper
image: chinaskill-zookeeper:v1.1
ports:
- containerPort: 2181
- name: kafka
image: chinaskill-kafka:v1.1
ports:
- containerPort: 9092
- name: nginx
image: chinaskill-nginx:v1.1
ports:
- containerPort: 80
command:
- sh
- -c
- "bash /opt/setup.sh && nginx -g 'daemon off;'"
---
apiVersion: v1
kind: Service
metadata:
name: chinaskill-mall
spec:
selector:
app: gpmall
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30010
gitlab push项目
[root@k8s-master-node2 gpmall]# git config --global user.name "Administrator"
[root@k8s-master-node2 gpmall]# git config --global user.email "admin@example.com"
[root@k8s-master-node2 gpmall]# git init
Initialized empty Git repository in /root/gpmall/.git/
[root@k8s-master-node2 gpmall]# git remote add origin git@192.168.0.12:81/root/gpmall.git
[root@k8s-master-node2 gpmall]# git add .
[root@k8s-master-node2 gpmall]# git commit -m "Initial commit"
[root@k8s-master-node1 gpmall]# git push -u origin master
配置CICD
jenkins
流水线
node{
stage('git clone'){
git credentialsId: '805c5026-5817-40aa-9d29-fef875e744da', url: 'http://192.168.0.10:81/root/gpmall.git'
}
stage('image build'){
sh'''
docker build -t 192.168.0.10/gpmall/chinaskill-mariadb:$BUILD_ID -f mariadb/Dockerfile mariadb
docker build -t 192.168.0.10/gpmall/chinaskill-redis:$BUILD_ID -f redis/Dockerfile redis
docker build -t 192.168.0.10/gpmall/chinaskill-kafka:$BUILD_ID -f kafka/Dockerfile kafka
docker build -t 192.168.0.10/gpmall/chinaskill-zookeeper:$BUILD_ID -f zookeeper/Dockerfile zookeeper
docker build -t 192.168.0.10/gpmall/chinaskill-nginx:$BUILD_ID -f nginx/Dockerfile nginx'''
}
stage('upload image'){
sh'''
docker login -u=admin -p=Harbor12345 192.168.0.10
docker push 192.168.0.10/gpmall/chinaskill-mariadb:$BUILD_ID
docker push 192.168.0.10/gpmall/chinaskill-redis:$BUILD_ID
docker push 192.168.0.10/gpmall/chinaskill-kafka:$BUILD_ID
docker push 192.168.0.10/gpmall/chinaskill-zookeeper:$BUILD_ID
docker push 192.168.0.10/gpmall/chinaskill-nginx:$BUILD_ID'''
}
stage('deploy project'){
sh'''
sed -i "s/chinaskill-mariadb:v1.1/192.168.0.10\\/gpmall\\/chinaskill-mariadb:$BUILD_ID/g" gpmall.yaml
sed -i "s/chinaskill-redis:v1.1/192.168.0.10\\/gpmall\\/chinaskill-redis:$BUILD_ID/g" gpmall.yaml
sed -i "s/chinaskill-kafka:v1.1/192.168.0.10\\/gpmall\\/chinaskill-kafka:$BUILD_ID/g" gpmall.yaml
sed -i "s/chinaskill-zookeeper:v1.1/192.168.0.10\\/gpmall\\/chinaskill-zookeeper:$BUILD_ID/g" gpmall.yaml
sed -i "s/chinaskill-nginx:v1.1/192.168.0.10\\/gpmall\\/chinaskill-nginx:$BUILD_ID/g" gpmall.yaml
kubectl apply -f gpmall.yaml'''
}
}
配置harbor
构建gpmall
[root@a144e8f18710 .kube]# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/gpmall 5/5 Running 0 2m47s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/chinaskill-mall NodePort 10.96.74.197 <none> 80:30010/TCP 2m47s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 25h
Istio项目
官网地址:https://istio.io/latest/zh/docs/concepts/traffic-management/
Istio 是什么?
云平台令使用它们的公司受益匪浅。但不可否认的是,上云会给 DevOps 团队带来压力。为了可移植性,开发人员必须使用微服务来构建应用,同时运维人员也正在管理着极端庞大的混合云和多云的部署环境。 Istio 允许您连接、保护、控制和观察服务。
从较高的层面来说,Istio 有助于降低这些部署的复杂性,并减轻开发团队的压力。它是一个完全开源的服务网格,作为透明的一层接入到现有的分布式应用程序里。它也是一个平台,拥有可以集成任何日志、遥测和策略系统的 API 接口。Istio 多样化的特性使您能够成功且高效地运行分布式微服务架构,并提供保护、连接和监控微服务的统一方法。
服务网格是什么?
Istio 解决了开发人员和运维人员所面临的从单体应用向分布式微服务架构转变的挑战。了解它是如何做到这一点的可以让我们更详细地理解 Istio 的服务网格。
术语服务网格用来描述组成这些应用程序的微服务网络以及它们之间的交互。随着服务网格的规模和复杂性不断的增长,它将会变得越来越难以理解和管理。它的需求包括服务发现、负载均衡、故障恢复、度量和监控等。服务网格通常还有更复杂的运维需求,比如 A/B 测试、金丝雀发布、速率限制、访问控制和端到端认证。
Istio 提供了对整个服务网格的行为洞察和操作控制的能力,以及一个完整的满足微服务应用各种需求的解决方案。
为什么使用 Istio?
通过负载均衡、服务间的身份验证、监控等方法,Istio 可以轻松地创建一个已经部署了服务的网络,而服务的代码只需很少 更改甚至无需更改。通过在整个环境中部署一个特殊的 sidecar 代理为服务添加 Istio 的支持,而代理会拦截微服务之间的所有网络通信,然后使用其控制平面的功能来配置和管理 Istio,这包括:
• 为 HTTP、gRPC、WebSocket 和 TCP 流量自动负载均衡。
• 通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制。
• 可插拔的策略层和配置 API,支持访问控制、速率限制和配额。
• 集群内(包括集群的入口和出口)所有流量的自动化度量、日志记录和追踪。
• 在具有强大的基于身份验证和授权的集群中实现安全的服务间通信。
Istio 为可扩展性而设计,可以满足不同的部署需求。
核心特性
Istio 以统一的方式提供了许多跨服务网络的关键功能:
流量管理
Istio 简单的规则配置和流量路由允许您控制服务之间的流量和 API 调用过程。Istio 简化了服务级属性(如熔断器、超时和重试)的配置,并且让它轻而易举的执行重要的任务(如 A/B 测试、金丝雀发布和按流量百分比划分的分阶段发布)。
有了更好的对流量的可视性和开箱即用的故障恢复特性,您就可以在问题产生之前捕获它们,无论面对什么情况都可以使调用更可靠,网络更健壮。
请参考流量管理文档 获取更多细节。
安全
Istio 的安全特性解放了开发人员,使其只需要专注于应用程序级别的安全。Istio 提供了底层的安全通信通道,并为大规模的服务通信管理认证、授权和加密。有了 Istio,服务通信在默认情况下就是受保护的,可以让您在跨不同协议和运行时的情况下实施一致的策略——而所有这些都只需要很少甚至不需要修改应用程序。
Istio 是独立于平台的,可以与 Kubernetes(或基础设施)的网络策略一起使用。但它更强大,能够在网络和应用层面保护pod到 pod 或者服务到服务之间的通信。
请参考安全文档 获取更多细节。
可观察性
Istio 健壮的追踪、监控和日志特性让您能够深入的了解服务网格部署。通过 Istio 的监控能力,可以真正的了解到服务的性能是如何影响上游和下游的;而它的定制 Dashboard 提供了对所有服务性能的可视化能力,并让您看到它如何影响其他进程。
Istio 的 Mixer 组件负责策略控制和遥测数据收集。它提供了后端抽象和中介,将一部分 Istio 与后端的基础设施实现细节隔离开来,并为运维人员提供了对网格与后端基础实施之间交互的细粒度控制。
所有这些特性都使您能够更有效地设置、监控和加强服务的 SLO。当然,底线是您可以快速有效地检测到并修复出现的问题。
请参考可观察性文档 获取更多细节。
平台支持
Istio 独立于平台,被设计为可以在各种环境中运行,包括跨云、内部环境、Kubernetes、Mesos 等等。您可以在 Kubernetes 或是装有 Consul 的 Nomad 环境上部署 Istio。Istio 目前支持:
• Kubernetes 上的服务部署
• 基于 Consul 的服务注册
• 服务运行在独立的虚拟机上
整合和定制
Istio 的策略实施组件可以扩展和定制,与现有的 ACL、日志、监控、配额、审查等解决方案集成。
1. 部署Bookinfo应用
(1)Bookinfo简介
Bookinfo应用模仿在线书店的一个分类,显示一本书的信息。页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。
Bookinfo应用分为四个单独的微服务:
● productpage:调用details和reviews两个微服务,用来生成页面;
● details:包含书籍的信息;
● reviews:包含书籍相关的评论,会调用ratings微服务;
● ratings:包含由书籍评价组成的评级信息。
reviews微服务有3个版本:
● v1版本不会调用ratings服务;
● v2版本会调用ratings服务,并使用1到5个黑色星形图标来显示评分信息;
● v3版本会调用ratings服务,并使用1到5个红色星形图标来显示评分信息。
Bookinfo应用的端到端架构如图所示:
图1
Bookinfo应用中的几个微服务是由不同的语言编写的。这些服务对Istio并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个服务、多个语言构成,并且reviews服务具有多个版本。
(2)部署应用程序
[root@k8s-master-node1 ~]# tar -zxvf ServiceMesh.tar.gz
[root@k8s-master-node1 ServiceMesh]# docker load < images/image.tar
[root@k8s-master-node1 ServiceMesh]# kubectl apply -f bookinfo/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created
查看pod状态
[root@k8s-master-node1 ServiceMesh]# kubectl get pod
NAME READY STATUS RESTARTS AGE
details-v1-79f774bdb9-8gqkf 1/1 Running 0 6m37s
productpage-v1-6b746f74dc-7r66g 1/1 Running 0 6m37s
ratings-v1-b6994bb9-b7vmb 1/1 Running 0 6m37s
reviews-v1-545db77b95-jndxc 1/1 Running 0 6m37s
(3)启用对应用程序的外部访问
现在Bookinfo应用程序已成功运行,需要使应用程序可以从外部访问,可以用Istio Gateway来实现这个目标。
使用网关为网格来管理入站和出站流量,可以指定要进入或流出网格的流量。网关配置被用于运行在网格边界的独立Envoy代理,而不是服务工作负载的sidecar代理。
与Kubernetes Ingress API这种控制进入系统流量的其他机制不同,Istio网关充分利用了流量路由的强大能力和灵活性。Istio的网关资源可以配置4-6层的负载均衡属性,如对外暴露的端口、TLS设置等。作为替代应用层流量路由(L7)到相同的API资源,绑定一个常规的Istio虚拟服务到网关,这样就可以像管理网格中其他数据平面的流量一样去管理网关流量。
网关主要用于管理进入的流量,也可以配置出口网关。出口网关为流出网格的流量配置一个专用的出口节点,这可以限制哪些服务可以或应该访问外部网络,或者启用出口流量安全控制为网格添加安全性。
Gateway配置文件如下:
[root@k8s-master-node1 ServiceMesh]# cat bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
这个网关指定所有HTTP流量通过80端口流入网格,然后把网关绑定到虚拟服务上。
为应用程序定义Ingress网关:
[root@k8s-master-node1 ServiceMesh]# kubectl apply -f bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created
[root@k8s-master-node1 ServiceMesh]# kubectl get gateway
NAME AGE
bookinfo-gateway 72s
查看Ingress Gateway:
[root@k8s-master-node1 ServiceMesh]# kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
grafana NodePort 10.96.70.234 <none> 3000:33000/TCP 46h
istio-egressgateway ClusterIP 10.96.44.159 <none> 80/TCP,443/TCP 46h
istio-ingressgateway LoadBalancer 10.96.213.206 <pending> 15021:30001/TCP,80:43098/TCP,443:15621/TCP,31400:43015/TCP,15443:57078/TCP 46h
istiod ClusterIP 10.96.174.48 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 46h
jaeger-collector ClusterIP 10.96.97.124 <none> 14268/TCP,14250/TCP,9411/TCP 46h
kiali NodePort 10.96.126.236 <none> 20001:20001/TCP,9090:9091/TCP 46h
prometheus NodePort 10.96.53.125 <none> 9090:30090/TCP 46h
tracing NodePort 10.96.213.41 <none> 80:30686/TCP,16685:30685/TCP 46h
zipkin ClusterIP 10.96.187.188 <none> 9411/TCP 46h
可以看到Gateway 80端口对应的NodePort端口是22092,在浏览器上通过http://master_IP:43098/productpage 访问Bookinfo应用,如图所示:
(3)生产测试
使用Curl工具每秒向Bookinfo应用发送1个请求,模拟用户流量:
[root@k8s-master-node1 ServiceMesh]# cat curl.sh
#!/bin/bash
while true
do
curl http://192.168.0.10:43098/productpage >/dev/null 2>&1
sleep 1
done
[root@k8s-master-node1 ServiceMesh]# bash curl.sh &
[1] 126540
3. 启用Istio
(1)在productpage启用Istio
在productpage微服务中,启用Istio。这个应用的其他部分会继续照原样运行。可以一个微服务一个微服务的逐步启用Istio。启用Istio在微服务中是无侵入的,不用修改微服务代码或者破坏应用,它也能够持续运行并且为用户请求服务。
在使用Istio控制Bookinfo版本路由之前,需要在目标规则中定义好可用的版本。目标规则是Istio流量路由功能的关键部分。可以将虚拟服务视为将流量如何路由到给定目标地址,然后使用目标规则来配置该目标的流量。在评估虚拟服务路由规则之后,目标规则将应用于流量的“真实”目标地址。
编写目标规则配置文件:
[root@k8s-master-node1 ServiceMesh]# cat destination-rule-all.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productpage
spec:
host: productpage
subsets:
- name: v1
labels:
version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: ratings
spec:
host: ratings
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v2-mysql
labels:
version: v2-mysql
- name: v2-mysql-vm
labels:
version: v2-mysql-vm
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: details
spec:
host: details
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
[root@k8s-master-node1 ServiceMesh]# kubectl apply -f destination-rule-all.yaml
destinationrule.networking.istio.io/productpage created
destinationrule.networking.istio.io/reviews created
destinationrule.networking.istio.io/ratings created
destinationrule.networking.istio.io/details created
[root@k8s-master-node1 ServiceMesh]# kubectl get destinationrule
NAME HOST AGE
details details 18s
productpage productpage 18s
ratings ratings 18s
reviews reviews 18s
重新部署productpage微服务,启用Istio:
[root@k8s-master-node1 ServiceMesh]# cat bookinfo/bookinfo.yaml | istioctl kube-inject -f - | kubectl apply -l app=productpage -f -
service/productpage unchanged
deployment.apps/productpage-v1 configured
检查productpage的Pod并且查看每个副本的两个容器。第一个容器是微服务本身的,第二个是连接到它的Sidecar代理:
[root@k8s-master-node1 ServiceMesh]# kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-79f774bdb9-8gqkf 1/1 Running 0 37m
productpage-v1-599f9dc7b8-fqbm9 2/2 Running 0 35s
ratings-v1-b6994bb9-b7vmb 1/1 Running 0 37m
reviews-v1-545db77b95-jndxc 1/1 Running 0 37m
Kubernetes采取无侵入的和逐步的滚动更新方式用启用Istio的Pod替换了原有的Pod。Kubernetes只有在新的Pod开始运行的时候才会终止老的Pod,它透明地将流量一个一个地切换到新的Pod上。也就是说,它不会在声明一个新的Pod之前结束一个或者以上的Pod。这些操作都是为了防止破坏应用,因此在注入Istio的过程中应用能够持续工作。
在浏览器上登录Grafana(http://master_IP:33000 )
依次点击左侧导航栏的“Dashboards” →“Manage”进入Dashboard管理界面
选择Istio Mesh Dashboard
切换到Istio Service Dashboard仪表盘,在Service中选择productpage
(2)在所有微服务中启用Istio
所有服务启用Istio:
[root@k8s-master-node1 ServiceMesh]# cat bookinfo/bookinfo.yaml | istioctl kube-inject -f - | kubectl apply -l app!=productpage -f -
service/details unchanged
serviceaccount/bookinfo-details unchanged
deployment.apps/details-v1 configured
service/ratings unchanged
serviceaccount/bookinfo-ratings unchanged
deployment.apps/ratings-v1 configured
service/reviews unchanged
serviceaccount/bookinfo-reviews unchanged
deployment.apps/reviews-v1 configured
serviceaccount/bookinfo-productpage unchanged
查看应用程序Pod,现在每个Pod的两个容器,一个容器是微服务本身,另一个是连接到它的Sidecar代理:
[root@k8s-master-node1 ServiceMesh]# kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-6df75fb475-jbwl7 2/2 Running 0 34s
productpage-v1-599f9dc7b8-fqbm9 2/2 Running 0 7m41s
ratings-v1-b6994bb9-b7vmb 1/1 Terminating 0 44m
ratings-v1-c7b9dfddc-fn6dd 2/2 Running 0 34s
reviews-v1-5485466448-q5gtn 2/2 Running 0 34s
再次查看Istio Mesh Dashboard,会发现当前命名空间下所有服务都会出现在服务列表中
访问Kiali控住台(http://master_IP:20001 )
通过可视化界面来查看应用程序的拓扑结构,点击“Graph”按钮,在Namespace下拉菜单中选择命名空间default,然后在Display下拉菜单中选中“Traffic Animation”和“Idle Nodes”复选框,就可以看到实时流量动画
4. 灰度发布
(1)部署新版本服务
将v2、v3版本的reviews服务部署到集群中,均为单一副本。新版本的reviews可以正常工作后,实际生产流量将开始到达该服务。在当前的设置下,50%的流量将到达旧版本(1个旧版本的Pod),而另外50%的流量将到达新版本(1个新版本Pod)。
部署v2版本的reviews微服务并开启Istio:
[root@k8s-master-node1 ServiceMesh]# cat bookinfo/reviews-v2.yaml | istioctl kube-inject -f - | kubectl apply -f -
deployment.apps/reviews-v2 created
[root@k8s-master-node1 ServiceMesh]# cat bookinfo/reviews-v3.yaml | istioctl kube-inject -f - | kubectl apply -f -
deployment.apps/reviews-v3 created
[root@k8s-master-node1 ServiceMesh]# kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-6df75fb475-jbwl7 2/2 Running 0 12m
productpage-v1-599f9dc7b8-fqbm9 2/2 Running 0 19m
ratings-v1-c7b9dfddc-fn6dd 2/2 Running 0 12m
reviews-v1-5485466448-q5gtn 2/2 Running 0 12m
reviews-v2-855b56b89-rkldp 2/2 Running 0 7m58s
reviews-v3-7b76df6bbb-4j7bx 2/2 Running 0 7m6s
观察评级上的星标,发现有时返回的页面带有黑色星标(v2版本、大约三分之一的时间),有时带有红色星标(v3版本、大约三分之一的时间),有时不带星标(v1版本、大约三分之一的时间),这是因为没有明确的默认服务版本和路由,Istio将以轮询方式将请求路由到所有可用版本,所以三种评分结果出现的概率均为三分之一。
查看实时流量监控
可以看到,v2和v3版本的reviews微服务已正常工作,因v2和v3版本会调用ratings服务,所以图中ratings服务也有流量通过。
(2)请求路由
Bookinfo应用程序包含四个独立的微服务,每个微服务都有多个版本。其中一个微服务reviews的3个不同版本已经部署并同时运行。因为没有明确的默认服务版本和路由,Istio将以轮询方式将请求路由到所有可用版本。这样将导致在浏览器中访问Bookinfo应用程序时,输出有时包含星级评分,有时则不包含。
Kubernetes方式下控制流量分配需要调整每个Deployment的副本数目。例如,将10%的流量发送到金丝雀版本(v2),v1和v2的副本可以分别设置为9和1。由于在启用Istio后不再需要保持副本比例,所以可以安全地设置Kubernetes HPA来管理三个版本Deployment的副本:
[root@k8s-master-node1 ServiceMesh]# kubectl autoscale deployment reviews-v1 --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/reviews-v1 autoscaled
[root@k8s-master-node1 ServiceMesh]# kubectl autoscale deployment reviews-v2 --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/reviews-v2 autoscaled
[root@k8s-master-node1 ServiceMesh]# kubectl autoscale deployment reviews-v3 --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/reviews-v3 autoscaled
如果要仅路由到一个版本,请为微服务设置默认版本的Virtual Service。在这种情况下,Virtual Service将所有流量路由到每个微服务的v1版本。
默认请求路由配置文件如下:
[root@k8s-master-node1 ServiceMesh]# cat virtual-service-all-v1.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productpage
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: details
spec:
hosts:
- details
http:
- route:
- destination:
host: details
subset: v1
[root@k8s-master-node1 ServiceMesh]# kubectl apply -f virtual-service-all-v1.yaml
virtualservice.networking.istio.io/productpage created
virtualservice.networking.istio.io/reviews created
virtualservice.networking.istio.io/ratings created
virtualservice.networking.istio.io/details created
现在已将Istio配置为路由到Bookinfo微服务的v1版本,最重要的是reviews服务的v1版本。
在浏览器中打开Bookinfo站点
此时无论刷新多少次,页面的评分部分都不会显示评级星标。这是因为Istio被配置为将评分服务的所有流量路由到v1版本的reviews,而此版本的服务不调用星级评分服务。
查看实时流量监控,也可以看到此时无流量流向v2和v3版本
Istio Bookinfo项目至此完成
Kubevirt项目
什么是 KubeVirt ?
Kubevirt 是Redhat开源的以容器方式运行虚拟机的项目,以k8s add-on方式,利用k8s CRD为增加资源类型VirtualMachineInstance(VMI), 使用容器的image registry去创建虚拟机并提供VM生命周期管理。 CRD的方式是的kubevirt对虚拟机的管理不局限于pod管理接口,但是也无法使用pod的RS DS Deployment等管理能力,也意味着 kubevirt如果想要利用pod管理能力,要自主去实现,目前kubevirt实现了类似RS的功能。 kubevirt目前支持的runtime是docker和runv。
为什么使用 KubeVirt ?
KubeVirt 技术可满足已采用或想要采用Kubernetes开发团队的需求,但他们拥有现有的基于虚拟机的工作负载,无法轻松地对其进行容器化。更具体地说,该技术提供了一个统一的开发平台,开发人员可以在该平台上构建,修改和部署驻留在公共共享环境中的应用程序容器和虚拟机中的应用程序。
好处是广泛而重大的。依赖现有基于虚拟机的工作负载团队有权快速将应用程序容器化。通过将虚拟化工作负载直接放置在开发工作流中,团队可以随时间分解它们,同时仍然可以按需使用剩余的虚拟化组件。
KubeVirt 能做什么 ?
• 利用 KubeVirt 和 Kubernetes 来管理虚拟机
• 一个平台上将现有的虚拟化与容器化打通并管理
• 支持虚拟机应用与容器化应用实现内部交互访问
Kubevirt的架构
kubevirt以CRD的形式将VM管理接口接入到kubernetes中,通过一个pod去使用libvirtd管理VM的方式,实现pod与VM的一一对应,做到如同容器一般去管理虚拟机,并且做到与容器一样的资源管理、调度规划、这一层整体与企业IAAS关系不大,也方便企业的接入,统一纳管。
virt-api:kubevirt是以CRD形式去管理VM Pod,virt-api就是所有虚拟化操作的入口,这里面包括常规的CDR更新验证、以及console、vm start、stop等操作。
virt-controller:virt-controller会根据vmi CRD,生成对应的virt-launcher Pod,并且维护CRD的状态。与kubernetes api-server通讯监控VMI资源的创建删除等状态。
virt-handler:virt-handler会以deamonset形式部署在每一个节点上,负责监控节点上的每个虚拟机实例状态变化,一旦检测到状态的变化,会进行响应并且确保相应的操作能够达到所需(理想)的状态。virt-handler还会保持集群级别VMI Spec与相应libvirt域之间的同步;报告libvirt域状态和集群Spec的变化;调用以节点为中心的插件以满足VMI Spec定义的网络和存储要求。
virt-launcher:每个virt-launcher pod对应着一个VMI,kubelet只负责virt-launcher pod运行状态,不会去关心VMI创建情况。virt-handler会根据CRD参数配置去通知virt-launcher去使用本地的libvirtd实例来启动VMI,随着Pod的生命周期结束,virt-lanuncher也会去通知VMI去执行终止操作;其次在每个virt-launcher pod中还对应着一个libvirtd,virt-launcher通过libvirtd去管理VM的生命周期,这样做到去中心化,不再是以前的虚拟机那套做法,一个libvirtd去管理多个VM。
virtctl:virtctl是kubevirt自带类似kubectl的命令行工具,它是越过virt-launcher pod这一层去直接管理VM虚拟机,可以控制VM的start、stop、restart。
虚拟机镜像制作与管理
虚拟机镜像采用容器镜像形式存放在镜像仓库中。创建原理如上图所示,将Linux发行版本的镜像文件存放到基础镜像的/disk目录内,镜像格式支持qcow2、raw、img。通过Dockerfile文件将虚拟机镜像制作成容器镜像,然后分别推送到不同的registry镜像仓库中。客户在创建虚拟机时,根据配置的优先级策略拉取registry中的虚拟机容器镜像,如果其中一台registry故障,会另一台健康的registry拉取镜像。
虚拟机生命周期管理
KubeVirt虚拟机生命周期管理主要分为以下几种状态:
l 虚拟机创建:创建VM对象,并同步创建DataVolume/PVC,从Harbor镜像仓库中拉取系统模板镜像拷贝至目标调度主机,通过调度、IP分配后生成VMI以及管理VM的Launcher Pod从而启动供业务使用的VM。
l 虚拟机运行:运行状态下的VM 可以进行控制台管理、快照备份/恢复、热迁移、磁盘热挂载/热删除等操作,此外还可以进行重启、下电操作,提高VM安全的同时解决业务存储空间需求和主机异常Hung等问题。
l 虚拟机关机:关机状态下的VM可以进行快照备份/恢复、冷迁移、CPU/MEM规格变更、重命名以及磁盘挂载等操作,同时可通过重新启动进入运行状态,也可删除进行资源回收。
l 虚拟机删除:对虚机资源进行回收,但VM所属的磁盘数据仍将保留、具备恢复条件。
虚拟机创建流程
虚拟机创建分为创建DataVolume和VMI两个流程:
1. 创建DataVolume后,CDI组件创建对应的PVC并且关联到合适的PV,然后通过临时Importer Pod拉取虚拟机容器镜像绑定到DataVolume生成的PV中,并且将镜像转换成disk.img文件存储在PV中供虚拟机使用。
2. 创建VMI后,等待disk.img转换成功,然后在对应的Node上启动Launcher Pod,并将CDI流程生成的PV挂载到Pod内,当做虚拟机启动的系统盘。Launcher根据VMI的定义生成定义虚拟机的XML文件,然后调用libvirt进程调用Qemu命令创建并且启动虚拟机。VMI会对Launcher Pod状态进行同步,反应VM运行的状态。
Client K8s API VMI CRD Virt Controller VMI Handler
-------------------------- ----------- ------- ----------------------- ---------- listen <----------- WATCH /virtualmachines
listen <----------------------------------- WATCH /virtualmachines
| |
POST /virtualmachines ---> validate | |
create ---> VMI ---> observe --------------> observe
| | v v
validate <--------- POST /pods defineVMI
create | | |
| | | |
schedPod ---------> observe |
| | v |
validate <--------- PUT /virtualmachines |
update ---> VMI ---------------------------> observe
| | | launchVMI
| | | |
: : : :
| | | |
DELETE /virtualmachines -> validate | | |
delete ----> * ---------------------------> observe
| | shutdownVMI
| | |
: : :
Kubevirt如何实现容器与虚拟机交互TBD
容器和虚拟机互通
l Virtual-Kubelet对应的Node会上报节点上Pod的Endpoint,假定Kubernetes集群和IaaS层平台部署在同一个二层网络下,则集群内容器Pod可以访问VM-Pod,但容器Pod对于VM-Pod不可见;
l 针对上一点可以通过Macvlan等网络插件,将容器-Pod,降维至二层网络上,实现容器-Pod和虚拟机互通,有一定硬件要求。
如何实现⼀套集群下虚拟机与容器的混合调度与资源隔离
l Virtual-Kubelet提供的是一个虚拟节点用来向Kubernetes上报Node对象和Pod的状态和资源情况,虚拟机资源和集群内节点资源完全隔离;
l 在引入Virtual-Kubelet的情况下,需要对Virtual-Kubelet节点配置Taint和Tolerations,保证容器-Pod和VM-Pod调度分离。
服务发现
Virtual-Kubelet,通过Provider实现的API将IaaS层VM信息抽象成对应Pod对象的信息的方式来上报Endpoints,可以通过给CR添加no selector Service,待VM-Pod拉起后补充address至对应的Service
Kubevirt适用场景
由于Kubervirt提供的成熟的虚拟化能力和性能,并且可以直接通过Kubernetes进行统一管理。所以Kubevirt适合在有PaaS层管理平台和Kubernetes集群环境的情况下,通过kubevirt中的单一控制平面简化了对虚拟机的管理,让用户无需关心IaaS层,即可轻松在集群内构建、部署出一台虚拟机进行使用。
案例实施
1.查看集群状态
[root@k8s-master-node1 ~]# kubectl get all -n kubevirt
NAME READY STATUS RESTARTS AGE
pod/virt-api-86f9d6d4f-8pn5d 1/1 Running 1 (22m ago) 47h
pod/virt-api-86f9d6d4f-b8wwz 1/1 Running 1 (22m ago) 47h
pod/virt-controller-54b79f5db-h8wzx 1/1 Running 1 (22m ago) 47h
pod/virt-controller-54b79f5db-qwg42 1/1 Running 2 (22m ago) 47h
pod/virt-handler-9wmgk 1/1 Running 1 (22m ago) 47h
pod/virt-handler-t9fsg 1/1 Running 1 (22m ago) 47h
pod/virt-handler-wgwjc 1/1 Running 1 (22m ago) 47h
pod/virt-operator-6fbd74566c-8zq2w 1/1 Running 1 (22m ago) 47h
pod/virt-operator-6fbd74566c-j4lsd 1/1 Running 2 47h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubevirt-operator-webhook ClusterIP 10.96.215.78 <none> 443/TCP 47h
service/kubevirt-prometheus-metrics ClusterIP 10.96.45.81 <none> 443/TCP 47h
service/virt-api ClusterIP 10.96.18.47 <none> 443/TCP 47h
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/virt-handler 3 3 3 3 3 kubernetes.io/os=linux 47h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/virt-api 2/2 2 2 47h
deployment.apps/virt-controller 2/2 2 2 47h
deployment.apps/virt-operator 2/2 2 2 47h
NAME DESIRED CURRENT READY AGE
replicaset.apps/virt-api-86f9d6d4f 2 2 2 47h
replicaset.apps/virt-controller-54b79f5db 2 2 2 47h
replicaset.apps/virt-operator-6fbd74566c 2 2 2 47h
NAME AGE PHASE
kubevirt.kubevirt.io/kubevirt 47h Deployed
virtctl版本
[root@k8s-master-node1 ~]# virtctl version
Client Version: version.Info{GitVersion:"v0.47.1", GitCommit:"c34de42a48f5564f4fd2c21b6cbda7b96664c65b", GitTreeState:"clean", BuildDate:"2021-11-11T16:01:45Z", GoVersion:"go1.16.6", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{GitVersion:"v0.47.1-dirty", GitCommit:"c34de42a48f5564f4fd2c21b6cbda7b96664c65b", GitTreeState:"dirty", BuildDate:"2021-11-11T16:20:45Z", GoVersion:"go1.16.6", Compiler:"gc", Platform:"linux/amd64"}
2.创建虚拟机
[root@k8s-master-node1 ~]# cat vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: testvm
spec:
running: false
template:
metadata:
labels:
kubevirt.io/size: small
kubevirt.io/domain: testvm
spec:
domain:
devices:
disks:
- name: containerdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {}
resources:
requests:
memory: 64M
networks:
- name: default
pod: {}
volumes:
- name: containerdisk
containerDisk:
image: quay.io/kubevirt/cirros-container-disk-demo
- name: cloudinitdisk
cloudInitNoCloud:
userDataBase64: SGkuXG4=
[root@k8s-master-node1 ~]# kubectl get vms #查看虚拟机
NAME AGE STATUS READY
testvm 31s Stopped False
[root@k8s-master-node1 ~]# virtctl start testvm #使用virtctl命令启动虚拟机
VM testvm was scheduled to start
[root@k8s-master-node1 ~]# kubectl get vmis
NAME AGE PHASE IP NODENAME READY
testvm 95s Running 10.244.1.10 k8s-worker-node1 True #虚拟机为running状态
#进入虚拟机
[root@k8s-master-node1 ~]# virtctl console testvm
[root@k8s-master-node1 ~]# cat vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: testvm
spec:
running: false
template:
metadata:
labels:
kubevirt.io/size: small
kubevirt.io/domain: testvm
spec:
domain:
devices:
disks:
- name: containerdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {}
resources:
requests:
memory: 64M
networks:
- name: default
pod: {}
volumes:
- name: containerdisk
containerDisk:
image: quay.io/kubevirt/cirros-container-disk-demo
- name: cloudinitdisk
cloudInitNoCloud:
userDataBase64: SGkuXG4=
[root@k8s-master-node1 ~]# kubectl get vms #查看虚拟机
NAME AGE STATUS READY
testvm 31s Stopped False
[root@k8s-master-node1 ~]# virtctl start testvm #使用virtctl命令启动虚拟机
VM testvm was scheduled to start
[root@k8s-master-node1 ~]# kubectl get vmis
NAME AGE PHASE IP NODENAME READY
testvm 95s Running 10.244.1.10 k8s-worker-node1 True #虚拟机为running状态
#进入虚拟机
[root@k8s-master-node1 ~]# virtctl console testvm
3.基本使用方法
创建vmi:
# kubectl create -f vmi.yaml
查看vmi:
# kubectl get vmis
删除vmi:
# kubectl delete vmis <vmi-name>
virtctl工具
virtctl是KubeVirt自带的类似于kubectl的命令行工具,可以直接管理虚拟机,可以控制虚拟机的start、stop、restart等。
启动虚拟机命令:
# virtctl start <vmi-name>
停止虚拟机命令:
# virtctl stop <vmi-name>
重启虚拟机命令:
# virtctl restart <vmi-name>
VMI资源启动虚拟机
#下载qcow2镜像
[root@k8s-master-node1 vmi]# wget http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-Azure-1907.qcow2
#安装制作镜像相关软件
[root@k8s-master-node1 ~]# yum -y install qemu-img
#制作镜像
[root@k8s-master-node1 vmi]# qemu-img convert -p -f qcow2 -O raw CentOS-7-x86_64-Azure-1907.qcow2 CentOS-1907.raw
[root@k8s-master-node1 ~]# mkdir disk
[root@k8s-master-node1 vmi]# mv CentOS-1907.raw ../disk/
#修改镜像权限,查看qemu_id
[root@k8s-master-node1 ~]# chown -R 107.107 disk/CentOS-1907.raw
[root@k8s-master-node1 ~]# ll disk/
total 1558872
-rw-r--r-- 1 qemu qemu 8589934592 Aug 1 11:37 CentOS-1907.raw
#修改云镜像密码:
[root@k8s-master-node1 ~]# yum -y install libguestfs-tools-c
[root@k8s-master-node1 ~]# systemctl restart libvirtd
[root@k8s-master-node1 ~]# virt-sysprep --root-password password:centos -a disk/CentOS-1907.raw
histDisk方式启动虚拟机:
复制到node节点:
#histDisk方式启动
[root@k8s-master-node1 kubevirt]# cat deploy/kubevirt-cr.yaml
---
apiVersion: kubevirt.io/v1
kind: KubeVirt
metadata:
name: kubevirt
namespace: kubevirt
spec:
certificateRotateStrategy: {}
configuration:
developerConfiguration:
# featureGates: []
featureGates:
- LiveMigration
- DataVolumes
- HotplugVolumes
- HostDisk
- Snapshot
customizeComponents: {}
imagePullPolicy: IfNotPresent
workloadUpdateStrategy: {}
[root@k8s-master-node1 ~]# scp -r disk/CentOS-1907.img k8s-worker-node1://root/disk/
创建虚拟机
[root@k8s-master-node1 ~]# cat virt-centos.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachineInstance
metadata:
name: centos
spec:
terminationGracePeriodSeconds: 30
domain:
resources:
requests:
memory: 1024M
devices:
disks:
- name: hostdisk
disk:
bus: virtio
volumes:
- name: hostdisk
hostDisk:
path: /root/disk/CentOS-1907.img
type: DiskOrCreate
[root@k8s-master-node1 ~]# kubectl apply -f virt-centos.yaml
virtualmachineinstance.kubevirt.io/centos created
[root@k8s-master-node1 ~]# kubectl get vmi
NAME AGE PHASE IP NODENAME READY
centos 12s Running 10.244.0.26 k8s-master-node1 True
testvm 37m Running 10.244.2.14 k8s-worker-node2 True
参考文档:
OpenStack:
官网:https://docs.openstack.org/train/configuration/
文献:
《OpenStack设计与实现》 英特尔开源技术中心编著 电子工业出版社
《OpenStack部署实践》 张子凡编著 人民邮电出版社
《OpenStack从零开始学》 卢万龙 周萌编著 电子工业出版社
Ceph:
官网:https://docs.ceph.com/en/quincy/
文献:
《鲲鹏分布式存储解决方案》华为技术有限公司编著 华为技术有限公司
《ceph运维手册》
《分布式存储之ceph》
Kubernetes:
文献:
《kubernetes权威指南》 龚正编著 第4版 电子工业出版社
《kubernetes深入剖析》
Istio:
Kubevirt:
CICD:
gitlab:https://docs.gitlab.com/ee/install/
jenkins:https://www.jenkins.io/zh/
- 点赞
- 收藏
- 关注作者
评论(0)