# k8s综合项目 **Repository Path**: hacker__007/k8s-comprehensive-project ## Basic Information - **Project Name**: k8s综合项目 - **Description**: 基于k8s+docker环境构建一个高可用,高性能的web集群 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 5 - **Created**: 2025-06-17 - **Last Updated**: 2025-06-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README @[TOC](项目目录) # 项目名称 **基于Kubernetes+Docker构建一个高可用,高性能的web集群** # 项目拓扑图 ![输入图片说明](%E6%9E%B6%E6%9E%84%E6%8B%93%E6%89%91%E5%9B%BE/K8S%E7%BB%BC%E5%90%88%E6%8B%93%E6%89%91%E5%9B%BE.png) # 项目环境 此项目需要的所有文件都已经在Gitee上传了,需要的可以去我的Gitee仓库自行取用。下面给出仓库地址:[https://gitee.com/JD30/k8s-comprehensive-project](https://gitee.com/JD30/k8s-comprehensive-project) ## 软件环境 * CentOS:CentOS Linux release 7.9.2009 (Core) * Ansible:v2.9.27 * Docker:v20.10.6 * Docker Compose:v2.16.0 * Kubernetes:v1.20.6 * Calico:calico/kube-controllers:v3.18.0 * Etcd:etcd:v3.4.13 * CoreDNS:coredns:v1.7.0 * JumpServer:v3.2.2 * Harbor:v2.1.0 * NFS-Utils: nfs-utils-2.5.4 * Ingress:nginx-ingress-controller:v1.1.0,kube-webhook-certgen:v1.1.1 * MySQL:mysql:v5.7.36 * Metrics-server:metrics-server:v0.6.0 * Dashboard:kubernetesui/dashboard:v2.4.0,kubernetesui/metrics-scraper:v1.0.7 * Prometheus:prom/prometheus:v2.0.0 * Node\_exporter:prom/node\_exporter:v1.3.1 * Grafana:grafana/grafana:v6.1.4 * Jenkins:Jenkins 2.346.3 LTS * Gitlab:gitlab-jh:v15.11.3 ## 硬件环境 * CentOS 7.9(12台 CPU 2核 内存4G 磁盘60G) # 简介 基于K8S+Docker环境构建一个高可用,高性能的web集群,模拟企业里的生产环境,利用K8S优秀的扩容能力与快速部署能力,部署Web,MySQL,NFS,Harbor,Prometheus,Gitlab,Jenkins环境。 1. **规划设计整个集群的架构,部署好防火墙、k8s单master的集群环境,1个master3个node点、相关的服务器。** 2. **部署ansible完成相关软件的自动化运维工作,部署防火墙服务器和堡垒机** 3. **将自己的开发的web接口系统制作成镜像,部署到k8s里作为web应用,采用HPA技术,当cpu使用率达到50%的时候,进行水平扩缩,最小20个,最多40个pod。** 4. **部署nfs服务器,为整个web集群提供数据,让所有的web 业务pod都取访问,通过pv和pvc、卷挂载实现。** 5. **使用探针(liveless、readiness、startup)的httpGet和exec方法对web业务pod进行监控,一旦出现问题马上重启,增强业务pod的可靠性。** 6. **启动MySQL的pod,为web业务提供数据库服务。** 7. **Prometheus+Grafana实现对K8S集群系统资源监控** 8. **安装k8s的Dashboard对整个集群资源进行掌控了解。** 9. **使用ingress给web业务做负载均衡** 10. **对k8s集群进行压力测试,了解其系统资源瓶颈** 11. **构建CI/CD环境,安装gitlab、Jenkins、harbor实现相关的代码发布、镜像制作、数据备份等流水线工作。** 12. **将日志收集解决方案融入。** ## IP地址规划 | 主机名 | IP地址 | | --- | --- | | windows客户机 | 192.168.2.240| | k8smaster | 192.168.2.7 | | k8snode1| 192.168.2.8| | k8snode2 | 192.168.2.9 | | k8snode3| 192.168.2.10 | | firewalld | 192.168.2.11 | | nfs | 192.168.2.12 | | ansible | 192.168.2.13 | | bastion | 192.168.2.14 | | gitlab | 192.168.2.15 | | jenkins | 192.168.2.16 | | harbor | 8.130.33.145 | # 详细步骤 一、准备10台全新虚拟机,按照IP规划配置好静态IP。安装部署Ansible,建立免密通道,对所有服务器进行统一配置。 --------------------------------------------------------------------------- ### 1.根据ip规划配置好静态ip ``` [root@k8smaster ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33 BOOTPROTO=static #静态配置ip NAME=ens33 #网卡名称ens33 DEVICE=ens33 #本机网卡ens33 ONBOOT=yes #开机启动 IPADDR=192.168.2.7 #ip地址 PREFIX=24 #子网掩码24 DNS1=114.114.114.114 #dns服务器114.114.114.114 GATEWAY=192.168.2.1 #我选择的是桥接网络,所以网关是路由器ip 192.168.31.1 [root@master ~]# service network restart #重启网络 Restarting network (via systemctl): [ 确定 ] [root@master ~]# ip add #查看ip [root@master ~]# ping www.baidu.com #测试能否上网 [root@master ~]# hostnamectl set-hostname k8smaster #修改指定主机名,方便辨认 [root@master ~]# su ``` 其他服务器的配置过程类似,我就不一一写明了 ### 2.建立免密通道 ``` [root@ansible ~]# ssh-keygen #生成密钥对--一路回车 [root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.7 #上传公钥到远程服务器--yes,然后输入远程服务器密码--k8smaster [root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.8 #k8snode1 [root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.9 #k8snode2 [root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.10 #k8snode3 [root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.11 #firewalld [root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.12 #nfs [root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.14 #bastion [root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.15 #gitlab [root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.2.16 #jenkins ``` ### 3.安装部署ansible ``` [root@ansible ~]# yum install -y epel-release [root@ansible ~]# yum install ansible ``` ### 4.编写主机清单,加入主机组 加入远程主机ip ``` [root@ansible ~]# cd /etc/ansible/ [root@ansible ansible]# ls ansible.cfg hosts roles [root@ansible ansible]# vim hosts [k8smaster] 192.168.2.7 k8smaster [k8snode] 192.168.2.8 k8snode1 192.168.2.9 k8snode2 192.168.2.10 k8snode3 [firewalld] 192.168.2.11 firewalld [nfs] 192.168.2.12 nfs [bastion] 192.168.2.14 bastion [gitlab] 192.168.2.15 gitlab [jenkins] 192.168.2.16 jenkins ``` ### 5.编写playbook,对所有服务器进行统一配置 ``` [root@ansible ansible]# vim k8s-init.yaml - name: init k8s cluster hosts: all become: true tasks: - name: Set SELinux in permissive mode selinux: policy: targeted state: disabled - name: Stop firewalld firewalld: state: stopped - name: Disable firewalld at boot systemd: name: firewalld.service enabled: no - name: Download new CentOS repository file get_url: url: https://mirrors.aliyun.com/repo/Centos-7.repo dest: /etc/yum.repos.d/CentOS-Base.repo mode: '0644' changed_when: true - name: Clean yum cache yum: name: '' state: clean changed_when: false - name: Update yum cache yum: name: '' state: latest changed_when: false - name: Upgrade all packages yum: name: '*' state: latest changed_when: false ...... ``` 此playbook持续更新,具体内容请看我Gitee上传的文件,以其为准。大家可以一起贡献自己的力量,使ansible能够真正对一个集群搭建做到完全,真正做到自动化运维一键部署,提高搭建效率。 **使用ansible中的copy模块上传源码包时,速度可能比较慢—可以考虑直接使用xshell里的xftp工具直接上传,不写playbook** 二、部署好Kubernetes集群 ------------------------------------------------------------------ **以下操作是在所有节点上操作的(可以利用XShell工具栏的开启所有会话功能)** ### 1.修改/etc/hosts文件,添加k8s集群里的主机和ip地址映射关系 ``` [root@k8smaster ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.2.7 k8smaster 192.168.2.8 k8snode1 192.168.2.9 k8snode2 192.168.2.10 k8snode3 [root@k8smaster ~]# ``` ### 2.关闭交换分区(Kubeadm初始化的时候会检测) `swapoff -a` 临时关闭 `vim /etc/fstab` 永久关闭(注释swap行) ### 3.加载相关内核模块 执行 ```bash modprobe br_netfilter ``` ```bash echo "modprobe br_netfilter" >> /etc/profile ``` "modprobe br_netfilter"命令用于在Linux系统中加载br_netfilter内核模块。这个模块是Linux内核中的一个网络桥接模块,它允许管理员使用iptables等工具对桥接到同一网卡的流量进行过滤和管理。 如果您要使用Linux系统作为路由器或防火墙,并且需要对来自不同网卡的数据包进行过滤、转发或NAT操作,那么加载br_netfilter模块是非常必要的。 ---- 执行 ```bash cat > /etc/sysctl.d/k8s.conf < kubeadm.yaml ``` 接下来修改此文件: ``` vim kubeadm.yaml 修改处: advertiseAddress: 192.168.2.7 name: k8smaster imageRepository: registry.aliyuncs.com/google_containers 添加处(注意添加位置): podSubnet: 10.244.0.0/16 #指定pod网段, 需要新增加这个 --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd ``` ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/1.png) ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/2.png) 根据我们自己的需求修改配置,比如修改 imageRepository 的值,kube-proxy 的模式为 ipvs(iptables效率低),初始化节点的时候需要指定cgroupDriver为systemd ### 10.基于kubeadm.yaml文件初始化k8s ```bash kubeadm init --config=kubeadm.yaml --ignore-preflight-errors=SystemVerification ``` 结果显示说明: ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/3.png) master上执行: ```bash mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config ``` node分别执行(各人不同): ```bash kubeadm join 192.168.2.7:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:f425801b3240b6524b578f06f546c5c091a12202a6b2db66db32666a15046431 ``` 若因为某些原因使自己忘记了这段代码,比如后天需要添加新的node,可以使用下面命令重新产生,然后在node上输入有关代码加入k8s集群: ``` kubeadm token create --print-join-command ``` ### 11.查看节点 ``` [root@k8smaster ~]# kubectl get node NAME STATUS ROLES AGE VERSION k8smaster NotReady control-plane,master 10m v1.20.6 k8snode1 NotReady 4m28s v1.20.6 k8snode2 NotReady 4m28s v1.20.6 k8snode3 NotReady 4m28s v1.20.6 ``` 可以看到各节点的ROLES角色为空,就表示这个节点是工作节点,可以更改为worker ```bash kubectl label node k8snode1 node-role.kubernetes.io/worker=worker kubectl label node k8snode2 node-role.kubernetes.io/worker=worker kubectl label node k8snode3 node-role.kubernetes.io/worker=worker ``` 注意:上面状态都是NotReady状态,说明没有安装网络插件 ### 12.安装kubernetes网络插件-Calico 上传calico.yaml到k8smaster1上,使用yaml文件安装calico 网络插件。 ```bash kubectl apply -f calico.yaml ``` ``` [root@k8smaster ~]# kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-6949477b58-spdm4 1/1 Running 0 2m59s calico-node-4pcbd 1/1 Running 0 2m59s calico-node-7rhm6 1/1 Running 1 2m59s calico-node-cpcdh 1/1 Running 0 2m59s coredns-7f89b7bc75-stfcj 1/1 Running 0 56m coredns-7f89b7bc75-vgz5l 1/1 Running 0 56m etcd-k8smaster 1/1 Running 0 56m kube-apiserver-k8smaster 1/1 Running 0 56m kube-controller-manager-k8smaster 1/1 Running 0 56m kube-proxy-s4fkb 1/1 Running 0 51m kube-proxy-s9jv6 1/1 Running 0 56m kube-proxy-v6zhd 1/1 Running 0 51m kube-scheduler-k8smaster 1/1 Running 0 56m ``` ### 13.测试 测试在k8s创建pod是否可以正常访问网络: ``` [root@k8smaster ~]# kubectl run busybox --image busybox:1.28 --image-pull-policy=IfNotPresent --restart=Never --rm -it- sh / # ping www.baidu.com PING www.baidu.com (14.119.104.254): 56 data bytes 64 bytes from 14.119.104.254: seq=0 ttl=53 time=20.995 ms ``` 测试coredns是否正常: busybox最新版本,nslookup会解析不到dns和ip,用指定版本 ``` [root@k8smaster ~]# kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox -- sh / # nslookup kubernetes.default.svc.cluster.local Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: kubernetes.default.svc.cluster.local Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local ``` 说明: 10.96.0.10 就是我们coreDNS的clusterIP,说明coreDNS配置好了。 解析内部Service的名称,是通过coreDNS去解析的。 ### 14.kubeadm初始化k8s证书过期解决方案 查看证书有效时间: ```bash openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -text |grep Not openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text |grep Not ``` 延长证书过期时间: 1.把update-kubeadm-cert.sh文件上传到各个节点 2.在各个节点上执行如下 1)给update-kubeadm-cert.sh证书授权可执行权限 ```bash chmod +x update-kubeadm-cert.sh ``` 2)执行下面命令,修改证书过期时间,把时间延长到10年 ```bash ./update-kubeadm-cert.sh all ``` 3)在节点查询Pod是否正常,能查询出数据说明证书签发完成 ```bash kubectl get pods -n kube-system ``` 4)再次查看证书有效期,可以看到会延长到10年 ```bash openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -text |grep Not openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text |grep Not ``` 三、部署nfs服务器 ------------------------------------------------ **为整个web集群提供数据,让所有的web业务pod都取访问,通过pv和pvc、卷挂载实现。** ### 1.搭建好nfs服务器 ``` [root@nfs ~]# yum install nfs-utils -y ``` **建议k8s集群内的所有的节点都安装nfs-utils软件,因为节点服务器里创建卷需要支持nfs网络文件系统** ### 2.设置共享目录 ``` [root@nfs ~]# vim /etc/exports [root@nfs ~]# cat /etc/exports /jd/web 192.168.2.0/24(rw,no_root_squash,sync) ``` ### 3.新建共享目录和index.html网页 ``` [root@nfs ~]# mkdir /jd/web -p && cd /jd/web/ [root@nfs web]# echo "welcome to jiangda's web" >index.html [root@nfs web]# ls index.html [root@nfs ~]# ll -d /jd/web/ drwxr-xr-x. 2 root root 6 May 12 09:06 /jd/web/ ``` ### 4.刷新nfs或者重新输出共享目录 ``` [root@nfs ~]# exportfs -arv /jd/web 192.168.2.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash) ``` ### 5.所有节点设置开机自启动(包括nfs) ``` [root@k8smaster ~]# systemctl restart nfs [root@k8smaster ~]# systemctl enable nfs Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service. ``` ### 6.测试 在k8s集群里的任意一个节点服务器上测试能否挂载nfs服务器共享的目录 ``` [root@k8snode2 ~]# mkdir /pv_pvc_nfs 新建挂载点目录 [root@k8snode2 ~]# mount 192.168.2.12:/jd/web /pv_pvc_nfs 挂载 [root@k8snode2 ~]# df -Th|grep nfs 192.168.2.12:/jd/web nfs4 38G 2.6G 35G 7% /pv_pvc_nfs [root@k8snode2 ~]# cat /pv_pvc_nfs/index.html welcome to jiangda's web [root@k8snode2 ~]# ``` ### 7.创建pv使用nfs服务器上的共享目录 ``` [root@k8smaster ~]# vim nfs-pv.yaml [root@k8smaster ~]# kubectl apply -f nfs-pv.yaml [root@k8smaster ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE jd-web-pv 10Gi RWX Retain Available nfs 3m26s ``` ### 8.创建pvc使用pv ``` [root@k8smaster ~]# vim pvc-nfs.yaml [root@k8smaster ~]# kubectl apply -f pvc-nfs.yaml persistentvolumeclaim/jd-web-pvc created [root@k8smaster ~]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE jd-web-pvc Bound jd-web-pv 10Gi RWX nfs 5s ``` 四、搭建Harbor ------------------------------------------------------------------------------------------------------------------ ### 1. 提前条件 安装好Docker和Docker Compose并启动好。本次实验环境是在阿里云服务器上操作。 Ali Cloud ECS 配置如图: ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/3125842134412.png) 安装好Docker和Docker Compose后查看是否安装成功: ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/43563162756.png) ### 2. 下载Harbor源码 若要下载最新版或者其他版本,可到官方文档或者github: [https://goharbor.io/docs/2.7.0/install-config/download-installer/](https://goharbor.io/docs/2.7.0/install-config/download-installer/) [https://github.com/goharbor/harbor/releases/](https://github.com/goharbor/harbor/releases/) 我这里就下载Harbor v2.1.0 要是官网或者github上下载慢的话,我提供一个百度网盘: 链接:[https://pan.baidu.com/s/1ir526Teht9-Q5IaREI3kug](https://pan.baidu.com/s/1ir526Teht9-Q5IaREI3kug) 提取码:yjih ### 3. 从Windows上传到linux服务器并解压 创建目录/root/harbor 传输 解压: ``` [root@JD30-aliyun ~]# mkdir harbor [root@JD30-aliyun ~]# cd harbor [root@JD30-aliyun harbor]# [root@JD30-aliyun harbor]# ls harbor-offline-installer-v2.1.0.tgz [root@JD30-aliyun harbor]# tar xf harbor-offline-installer-v2.1.0.tgz [root@JD30-aliyun harbor]# ls harbor harbor-offline-installer-v2.1.0.tgz [root@JD30-aliyun harbor]# cd harbor [root@JD30-aliyun harbor]# ls common.sh harbor.v2.1.0.tar.gz harbor.yml.tmpl install.sh LICENSE prepare [root@JD30-aliyun harbor]# ll total 545268 -rw-r--r-- 1 root root 3361 Sep 16 2020 common.sh -rw-r--r-- 1 root root 558317240 Sep 16 2020 harbor.v2.1.0.tar.gz -rw-r--r-- 1 root root 8136 Sep 16 2020 harbor.yml.tmpl -rwxr-xr-x 1 root root 2523 Sep 16 2020 install.sh -rw-r--r-- 1 root root 11347 Sep 16 2020 LICENSE -rwxr-xr-x 1 root root 1881 Sep 16 2020 prepare [root@JD30-aliyun harbor]# ``` 当前路径: ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/2343534645234.png) ### 4. 调整配置 #### 4.1 从.yml.tmpl拷贝一份.yml文件 ``` [root@JD30-aliyun harbor]# cp harbor.yml.tmpl harbor.yml [root@JD30-aliyun harbor]# ll total 545276 -rw-r--r-- 1 root root 3361 Sep 16 2020 common.sh -rw-r--r-- 1 root root 558317240 Sep 16 2020 harbor.v2.1.0.tar.gz -rw-r--r-- 1 root root 8136 Mar 14 13:49 harbor.yml -rw-r--r-- 1 root root 8136 Sep 16 2020 harbor.yml.tmpl -rwxr-xr-x 1 root root 2523 Sep 16 2020 install.sh -rw-r--r-- 1 root root 11347 Sep 16 2020 LICENSE -rwxr-xr-x 1 root root 1881 Sep 16 2020 prepare ``` #### 4.2 修改harbor.yml文件 修改了:hostname: 8.130.33.145 和 port: 8089; 注释掉了https的配置; 其他的配置没有修改。 ```bash vim harbor.yml ``` ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/235234234353.png) ### 5. 安装 给install.sh可执行权限,并且将其脚本里的"docker-compose"改成"docker compose"。注意还有一个地方,在脚本前就能看到,一定要改common.sh,把这里面的"docker-compose"改成"docker compose"就改完全了~ 启动执行: ``` [root@JD30-aliyun harbor]# ./install.sh --with-chartmuseum [Step 0]: checking if docker is installed ... Note: docker version: 23.0.1 [Step 1]: checking docker compose is installed ... Note: docker compose version: 2.16.0 [Step 2]: loading Harbor images ... ✔ ----Harbor has been installed and started successfully.---- ``` 在部署harbor的时候,记得启用Harbor的Chart仓库服务(–with-chartmuseum),Helm 可以把打包好的chart 放入到harbor 中。 ### 6. 在windows机器上访问网站,去配置harbor 1. 访问:8.130.33.145:8089 2. 登录harbor 默认的登录的用户名和密码 admin Harbor12345 3. 新建项目 新建项目 jd ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/325476875643524.png) ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/234546788.png) 五、将自己的开发的web接口系统制作成镜像,推到harbor,再从harbor拉取镜像,部署到k8s里作为web应用,使用探针技术对web业务pod进行监控(httpGet),并采用HPA技术,当cpu使用率达到50%的时候,进行水平扩缩,最小20个,最多40个pod。 ------------------------------------------------------------------------------------------------------------------ ### 1.编写Dockerfile文件 ``` [root@nfs ~]# tar xf apiserver.tar.gz [root@nfs ~]# mkdir go [root@nfs ~]# cp apiserver/jdweb go/ [root@nfs go]# vim Dockerfile [root@nfs go]# ls Dockerfile jdweb [root@nfs go]# docker build -t jdweb:1.0 . [root@nfs go]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE jdweb 1.0 122282d864f8 About a minute ago 214MB ``` ### 2.上传镜像到Harbor 使用这个仓库: ``` [root@nfs go]# vim /etc/docker/daemon.json [root@nfs go]# systemctl daemon-reload && systemctl restart docker ``` ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/4.png) 登录harbor(账号:admin 密码:Harbor12345) ``` [root@nfs go]# docker login 8.130.33.145:8089 Username: admin Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded ``` 修改镜像的名字 给镜像打标签,标记本地镜像,将其归入某一仓库,也就是Harbor里的路径。 ``` [root@nfs go]# docker tag jdweb:1.0 8.130.33.145:8089/jd/jdweb ``` 把镜像push到Harbor上 ```bash docker push 8.130.33.145:8089/jd/jdweb ``` k8s集群每个节点都登入到harbor中,完成类似上面的配置操作,以便于从harbor中拉回镜像。 ``` [root@k8smaster ~]# vim /etc/docker/daemon.json [root@k8smaster ~]# systemctl daemon-reload && systemctl restart docker ``` ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/4.png) 登录harbor(账号:admin 密码:Harbor12345) ``` [root@k8smaster ~]# docker login 8.130.33.145:8089 Username: admin Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded ``` 拉取镜像(实测很慢) ``` [root@k8smaster ~]# docker pull 8.130.33.145:8089/jd/jdweb ``` ### 3.使用探针技术对web业务pod进行监控(httpGet) 在jd-web.yaml增加内容: ```bash readinessProbe: httpGet: path: / port: 8000 ``` ### 4.采用HPA技术启动Web 便于待会个性化启动pod(当cpu使用率达到50%的时候,进行水平扩缩,最小20个,最多40个pod) 在阿里云官方下载的yaml文件(metrics-server:v0.6.0) ``` [root@k8smaster ~]# kubectl apply -f components.yaml [root@k8smaster ~]# kubectl top node NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% k8smaster 467m 23% 1285Mi 35% k8snode1 211m 10% 677Mi 18% k8snode2 230m 11% 663Mi 18% ``` 启动pod,发布service: ``` [root@k8smaster ~]# vim jd-web.yaml [root@k8smaster ~]# kubectl apply -f jd-web.yaml deployment.apps/jd-web-deployment unchanged service/jd-web-service created ``` 浏览器访问任意节点(http://192.168.2.8:30001/sd/disk)如图,成功 ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/5.png) (思考:nfs能提供些什么,比如nfs能为我的nginx的pod,挂载时指定一下就可以monutPath在/usr/share/nginx/html一样的效果) (思考:我的deployment+hpa+service全放入yaml文件了,启动不了,可能低版本不支持hpa) 那就手动进行HPA缩放pod吧 因为我使用的是 kubectl 工具,运行以下命令创建 HPA: 创建 HPA 当cpu使用率达到50%的时候,进行水平扩缩,最小20个,最多40个pod ```bash kubectl autoscale deployment jd-web-deployment --cpu-percent=50 --min=20 --max=40 ``` 创建成功 ``` [root@k8smaster ~]# kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE jd-web-deployment Deployment/jd-web-deployment 0%/50% 20 40 20 35s ``` 六、启动一个单实例有状态MySQL的pod ------------------------------------------------------------------------------------------------------------------ ### 1.部署MySQL 要启动MySQL的Pod并为Web业务提供数据库服务,可以使用Kubernetes中的StatefulSet资源来管理MySQL的Pod。 您可以通过创建 Kubernetes 部署来运行有状态应用程序 并将其连接到现有的持久卷,使用 PersistentVolumeClaim.例如,`mysql-deployment.yaml`此文件描述了一个运行 MySQL 并引用 PersistentVolumeClaim 的部署。该文件为 /var/lib/mysql 定义卷挂载,然后创建一个 PersistentVolumeClaim,`mysql-pv.yaml`。 注意:密码是在配置 yaml 中定义的,这是不安全的。请参阅 Kubernetes Secrets 了解安全的解决方案。 ``` [root@k8smaster mysql]# vim mysql-deployment.yaml [root@k8smaster mysql]# vim mysql-pv.yaml [root@k8smaster mysql]# kubectl apply -f . service/mysql created deployment.apps/mysql created persistentvolume/mysql-pv-volume created persistentvolumeclaim/mysql-pv-claim created [root@k8smaster mysql]# kubectl describe deployment mysql Name: mysql Namespace: default CreationTimestamp: Mon, 15 May 2023 04:49:10 -0400 Labels: Annotations: deployment.kubernetes.io/revision: 1 Selector: app=mysql Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: Recreate MinReadySeconds: 0 Pod Template: Labels: app=mysql Containers: mysql: Image: mysql:5.7 Port: 3306/TCP Host Port: 0/TCP Environment: MYSQL_ROOT_PASSWORD: Jd123456 Mounts: /var/lib/mysql from mysql-persistent-storage (rw) Volumes: mysql-persistent-storage: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: mysql-pv-claim ReadOnly: false Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: NewReplicaSet: mysql-68b6967849 (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 20s deployment-controller Scaled up replica set mysql-68b6967849 to 1 [root@k8smaster mysql]# kubectl get pods -l app=mysql NAME READY STATUS RESTARTS AGE mysql-68b6967849-c8tpk 1/1 Running 0 47s [root@k8smaster mysql]# kubectl describe pvc mysql-pv-claim Name: mysql-pv-claim Namespace: default StorageClass: manual Status: Bound Volume: mysql-pv-volume Labels: Annotations: pv.kubernetes.io/bind-completed: yes pv.kubernetes.io/bound-by-controller: yes Finalizers: [kubernetes.io/pvc-protection] Capacity: 20Gi Access Modes: RWO VolumeMode: Filesystem Used By: mysql-68b6967849-c8tpk Events: ``` ### 2.访问 MySQL 实例 ``` [root@k8smaster mysql]# kubectl run -it --rm --image=mysql:5.7 --restart=Never mysql-client -- mysql -h mysql -pJd123456 If you don't see a command prompt, try pressing enter. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.01 sec) mysql> exit Bye pod "mysql-client" deleted [root@k8smaster mysql]# ``` 此命令在运行 MySQL 客户端的集群中创建一个新的 Pod 并通过服务将其连接到服务器。如果它连接,则您 知道您的有状态 MySQL 数据库已启动并正在运行。 ### 3.其余探索 最初MySQL的尝试: ``` [root@k8smaster ~]# kubectl apply -f mysql-pv.yaml persistentvolume/jd-mysql-pv created 启动pod前一定记得在nfs server上exports!!!! [root@nfs /]# vim /etc/exports [root@nfs /]# exportfs -rv exporting 192.168.2.0/24:/jd/mysql exporting 192.168.2.0/24:/jd/web [root@k8smaster ~]# vim mysql-pod.yaml [root@k8smaster ~]# kubectl apply -f mysql-pod.yaml persistentvolumeclaim/mysql-pv-claim created service/mysql created deployment.apps/mysql created [root@k8smaster ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE jd-mysql-pv 10Gi RWX Retain Bound default/mysql-pv-claim nfs 12m jd-web-pv 10Gi RWX Retain Bound default/jd-web-pvc nfs 6h51m [root@k8smaster ~]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE jd-web-pvc Bound jd-web-pv 10Gi RWX nfs 6h43m mysql-pv-claim Bound jd-mysql-pv 10Gi RWX nfs 10s 启动成功 [root@k8smaster ~]# kubectl get pod -o wide|grep mysql mysql-6d9dcf699-pwfm4 1/1 Running 0 15m 10.244.185.225 k8snode2 [root@k8smaster ~]# kubectl exec -it mysql-6d9dcf699-pwfm4 -- bash root@mysql-6d9dcf699-pwfm4:/# mysql -uroot -pJd123456 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.7.36 MySQL Community Server (GPL) Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> exit ``` 说明: 用navicat访问node2节点(为了数据库的安全,还是不暴露服务到外网,可以设置访问控制规则,目前先过) 将clusterIP: None设置为Service的规范,表示创建一个Headless Service。 Headless Services是一种类型的Kubernetes服务,它没有指定cluster IP地址,而是直接暴露了后端Pod的DNS名称。 这对于某些特定的用例非常有用,例如在进行数据库集群的时候。在这种情况下,每个Pod都会使用唯一的网络标识符,因此可以通过它们的主机名进行直接通信,而不需要通过负载均衡器或其他代理层。通过这种方式,可以提高性能并减少网络延迟。 另外,如果您想获取Service中所有Pod的IP地址,则可以使用DNS查询来实现,而不必访问整个Service的IP地址。 ### 4.Web服务和MySQL数据库结合起来 需要对相关yaml文件进行改动(**注意添加的位置是属于哪个属性,可以结合exipain命令**) 在mysql的service中增加内容: ```bash ports: - name: mysql protocol: TCP port: 3306 targetPort: 3306 ``` 这个Service使用标签选择器 app: mysql 来查找你的MySQL Pod,并将其绑定到端口3306。你可以根据需要更改端口。 在web的pod中增加内容: ```bash env: - name: MYSQL_HOST value: mysql - name: MYSQL_PORT value: "3306" ``` 这里我们将 MYSQL_HOST 环境变量设置为 mysql。由于我们在定义了Service名称为mysql,因此Pod应该能够通过该名称找到MySQL Service。 七、Prometheus+Grafana实现对K8S集群系统资源监控 ------------------------------------------------------------------------------------------------------------------ ### 1.在所有节点提前下载镜像 ``` [root@k8smaster ~]# docker pull prom/node-exporter [root@k8smaster ~]# docker pull prom/prometheus:v2.0.0 [root@k8smaster ~]# docker pull grafana/grafana:6.1.4 ``` ### 2.采用daemonset方式部署node-exporter ``` [root@k8smaster ~]# vim node-exporter.yaml [root@k8smaster ~]# kubectl apply -f node-exporter.yaml daemonset.apps/node-exporter created service/node-exporter created [root@k8smaster ~]# kubectl get pods -A|grep node-exporter kube-system node-exporter-bwpgl 1/1 Running 0 35s kube-system node-exporter-qq9xh 1/1 Running 0 34s 新的daemonset: [root@k8smaster ~]# kubectl get daemonset -A|grep node-exporter NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE kube-system node-exporter 2 2 2 2 2 109s 新的服务: [root@k8smaster ~]# kubectl get service -A|grep node-exporter kube-system node-exporter NodePort 10.99.112.193 9100:31672/TCP 3m5s ``` ### 3.部署prometheus ``` [root@k8smaster ~]# kubectl apply -f rbac-setup.yaml clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created [root@k8smaster ~]# kubectl apply -f configmap.yaml configmap/prometheus-config created [root@k8smaster ~]# kubectl apply -f prometheus.deploy.yml deployment.apps/prometheus created [root@k8smaster ~]# kubectl apply -f prometheus.svc.yml service/prometheus created [root@k8smaster ~]# ``` ### 4.部署grafana ``` [root@k8smaster ~]# kubectl apply -f grafana-deploy.yaml deployment.apps/grafana-core created [root@k8smaster ~]# kubectl apply -f grafana-svc.yaml service/grafana created [root@k8smaster ~]# kubectl apply -f grafana-ing.yaml ingress.networking.k8s.io/grafana created 检查: kubectl get pods -A kube-system grafana-core-78958d6d67-bqjpc 1/1 Running 0 27m kube-system node-exporter-bwpgl 1/1 Running 0 8m1s kube-system node-exporter-qq9xh 1/1 Running 0 8m kube-system prometheus-68546b8d9-std92 1/1 Running 0 3m17s kubectl get svc -A kube-system grafana NodePort 10.99.212.142 3000:30529/TCP 26m kube-system node-exporter NodePort 10.99.112.193 9100:31672/TCP 8m23s kube-system prometheus NodePort 10.110.124.68 9090:30003/TCP 3m32s ``` ### 5.测试 下面访问任意节点: #### 5.1 访问`http://192.168.2.7:31672/metrics` 这是node-exporter采集的数据 ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/6.png) ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/7.png) #### 5.2 访问`http://192.168.2.7:30003` 这是Prometheus的页面,依次点击Status——Targets可以看到已经成功连接到k8s的apiserver ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/8.png) #### 5.3 访问http://192.168.2.7:30529 这是grafana的页面,账户、密码都是admin ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/9.png) 进来改密码Jd123456 ### 6.配置监控 ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/10.png) URL需要写成,service.namespace:port 的格式,例如: 根据kubectl get svc -A的结果 以这里为例,namespace是kube-system,service是prometheus,pod端口是9090 那么最后的URL就是 http://prometheus.kube-system:9090 把K8S的Dashboard的模板导入(315模板) name自定义,uid可以为空,会自己生成,然后选择数据源,选择刚才创建的Prometheus,最后点击import ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/11.png) 效果图: ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/12.png) 八.安装Dashboard对整个集群资源进行掌控了解 ------------------------------------------------------------------------------------------------------------------ ### 1.各节点拉取镜像 ``` [root@k8smaster ~]# docker pull kubernetesui/dashboard:v2.4.0 [root@k8smaster ~]# docker pull kubernetesui/metrics-scraper:v1.0.7 ``` ### 2.部署官方版Dashboard ``` [root@k8smaster ~]# vim recommended.yaml [root@k8smaster ~]# kubectl apply -f recommended.yaml namespace/kubernetes-dashboard created serviceaccount/kubernetes-dashboard created service/kubernetes-dashboard created secret/kubernetes-dashboard-certs created secret/kubernetes-dashboard-csrf created secret/kubernetes-dashboard-key-holder created configmap/kubernetes-dashboard-settings created role.rbac.authorization.k8s.io/kubernetes-dashboard created clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created deployment.apps/kubernetes-dashboard created service/dashboard-metrics-scraper created deployment.apps/dashboard-metrics-scraper created [root@k8smaster ~]# kubectl get pod --all-namespaces kubernetes-dashboard dashboard-metrics-scraper-5b8896d7fc-gw852 1/1 Running 0 44s kubernetes-dashboard kubernetes-dashboard-897c7599f-xfwnw 1/1 Running 0 44s ``` **因为发布服务的类型是ClusterIP ,外面的机器不能访问,不便于我们通过浏览器访问,因此需要改成NodePort型的。 所以删除现有的dashboard服务** ``` [root@k8smaster ~]# kubectl delete service kubernetes-dashboard --namespace=kubernetes-dashboard service "kubernetes-dashboard" deleted ``` ### 3.创建配置文件(一个nodeport的service) ``` [root@k8smaster ~]# vim dashboard-svc.yaml [root@k8smaster ~]# kubectl apply -f dashboard-svc.yaml service/kubernetes-dashboard created ``` ### 4.想要访问dashboard服务,就要有访问权限,创建kubernetes-dashboard管理员角色 ``` [root@k8smaster ~]# vim recommended.yaml [root@k8smaster ~]# vim dashboard-svc-account.yaml [root@k8smaster ~]# kubectl apply -f dashboard-svc-account.yaml serviceaccount/dashboard-admin created clusterrolebinding.rbac.authorization.k8s.io/dashboard-admin created ``` ### 5.获取token ``` 先获得dashboard的secret对象的名字: [root@k8smaster ~]# kubectl get secret -n kube-system|grep admin|awk '{print $1}' dashboard-admin-token-lhdpj 再获得到secret里的token的内容: [root@k8smaster ~]# kubectl describe secret dashboard-admin-token-lhdpj -n kube-system|awk '/^token/ {print $2}' eyJhbGciOiJSUzI1NiIsImtpZCI6IjZNdklHbFRwWFZYcmdoTnRGcXEyQXZia0JaM0phZUY2WFJlZHZBTFR0ZjgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tbGhkcGoiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiMjA3MjgzZDItYjBlZS00ODRkLTg3NzEtNjAxMDFkMDYwMmQxIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.YHBMcUO-QmHJD3CZ8MA1BA7t4wFDbrm3glE2XHebmTdMVicnbJIUD3XUy2ntJ_shB4IcLEEzjEWb3e7eUUQl61FUMe_YemUBYxiJmukcv8IwDn0lPYf9EV0rmWTtbjXiZolV1pLBvcKgYeNRim1Mzu4utWrsjko4FAThK2CRHo6P1ApB04zkaEa1W5P8nfMlv9Iv-yesMTheRUiwKLWATpuLTO6Yw-FoVlPjShvhFmVuhOce9YOK1HGS6bahifyDLJ8wQvtURQoiQOZiVWU_fCzYCDWZv1njvbB4_x9ICbCJxLgXHxwcS0Ue-csj6S3-JYgtwoVoM0sM3U1YJIyW-A ``` ### 6.测试访问 #### 6.1 端口可以这样看到 ``` [root@k8smaster ~]# kubectl get svc -A|grep dash kubernetes-dashboard dashboard-metrics-scraper ClusterIP 10.105.9.199 8000/TCP 14m kubernetes-dashboard kubernetes-dashboard NodePort 10.104.224.172 443:30537/TCP 9m25s ``` #### 6.2 访问https://192.168.2.7:30537 若进不去:敲击"thisisunsasfe"即可进入,输入token ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/13.png) #### 6.3 登录后效果图 因为我们是基于域名做的负载均衡的配置,所有必须要在浏览器里使用域名去访问,不能使用ip地址 同时ingress controller做负载均衡的时候是基于http协议的,7层负载均衡 ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/14.png) ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/15.png) 九.使用ingress给web业务做负载均衡 ------------------------------------------------------------------------------------------------------------------ ### 1.安装ingress controller 将镜像scp到所有的node节点服务器上 ``` [root@k8smaster ~]# scp ingress-nginx-controllerv1.1.0.tar.gz k8snode1:/root ingress-nginx-controllerv1.1.0.tar.gz 100% 276MB 27.5MB/s 00:10 [root@k8smaster ~]# scp ingress-nginx-controllerv1.1.0.tar.gz k8snode2:/root ingress-nginx-controllerv1.1.0.tar.gz 100% 276MB 13.8MB/s 00:20 [root@k8smaster ~]# scp ingress-nginx-controllerv1.1.0.tar.gz k8snode3:/root ingress-nginx-controllerv1.1.0.tar.gz 100% 276MB 13.8MB/s 00:30 [root@k8smaster ~]# scp kube-webhook-certgen-v1.1.0.tar.gz k8snode1:/root kube-webhook-certgen-v1.1.0.tar.gz 100% 47MB 25.6MB/s 00:01 [root@k8smaster ~]# scp kube-webhook-certgen-v1.1.0.tar.gz k8snode2:/root kube-webhook-certgen-v1.1.0.tar.gz 100% 47MB 16.6MB/s 00:02 [root@k8smaster ~]# scp kube-webhook-certgen-v1.1.0.tar.gz k8snode3:/root kube-webhook-certgen-v1.1.0.tar.gz 100% 47MB 16.6MB/s 00:03 ``` 导入镜像,在所有的节点服务器上进行 ``` [root@k8smaster ~]# docker load -i ingress-nginx-controllerv1.1.0.tar.gz [root@k8smaster ~]# docker load -i kube-webhook-certgen-v1.1.0.tar.gz ``` 执行ingress-controller-deploy.yaml 文件,去启动ingress controller ``` [root@k8smaster ~]# kubectl apply -f ingress-controller-deploy.yaml namespace/ingress-nginx created serviceaccount/ingress-nginx created configmap/ingress-nginx-controller created clusterrole.rbac.authorization.k8s.io/ingress-nginx created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created role.rbac.authorization.k8s.io/ingress-nginx created rolebinding.rbac.authorization.k8s.io/ingress-nginx created service/ingress-nginx-controller-admission created service/ingress-nginx-controller created deployment.apps/ingress-nginx-controller created ingressclass.networking.k8s.io/nginx created validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created serviceaccount/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created role.rbac.authorization.k8s.io/ingress-nginx-admission created rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created job.batch/ingress-nginx-admission-create created job.batch/ingress-nginx-admission-patch created ``` 查看: ``` [root@k8smaster ~]# kubectl get ns|grep ingress ingress-nginx Active 66s [root@k8smaster ~]# kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.103.57.102 80:31854/TCP,443:31948/TCP 81s ingress-nginx-controller-admission ClusterIP 10.108.86.147 443/TCP 81s ``` ### 2.启用ingress 关联ingress controller 和service ``` [root@k8smaster ~]# vim jd-web-ing.yaml [root@k8smaster ~]# kubectl apply -f jd-web-ing.yaml ingress.networking.k8s.io/sc-ingress created ``` 查看效果:有宿主机的ip地址 ``` [root@k8smaster ~]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE sc-ingress nginx www.jdweb.com 192.168.2.8,192.168.2.9 80 36s ``` ### 3.查看ingress controller 里的nginx.conf 文件里是否有ingress对应的规则 ``` [root@k8smaster ~]# kubectl get pod -n ingress-nginx NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-bxdfk 0/1 Completed 0 9m22s ingress-nginx-admission-patch-dh8df 0/1 Completed 1 9m22s ingress-nginx-controller-6c8ffbbfcf-lzr8d 1/1 Running 0 9m23s ingress-nginx-controller-6c8ffbbfcf-rk8tk 1/1 Running 0 9m23s ``` 进入ingress controller对应的pod里查看nginx.conf的配置 ``` [root@k8smaster ~]# kubectl exec -n ingress-nginx -it ingress-nginx-controller-6c8ffbbfcf-lzr8d -- bash bash-5.1$ cat nginx.conf(很多upstream等等) [root@k8smaster ~]# kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.103.57.102 80:31854/TCP,443:31948/TCP 15m ingress-nginx-controller-admission ClusterIP 10.108.86.147 443/TCP 15m ``` ### 4.测试访问 在其他的任意宿主机或者windows机器上使用域名进行访问 ```bash vim /etc/hosts 192.168.2.8 www.jdweb.com 192.168.2.9 www.jdweb.com 192.168.2.10 www.jdweb.com ``` ``` [root@nfs ~]# curl www.jdweb.com hello,三创人 nice 2022[root@nfs ~]# [root@nfs ~]# curl www.jdweb.com:30001 hello,三创人 nice 2022[root@nfs ~]# ``` 浏览器访问: ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/16.png) 说明负载均衡完成 使用ingress controller暴露服务,不需要使用30000以上的端口访问,可以直接访问80或者443 比使用service暴露服务还是有点优势 十.对k8s集群进行压力测试,了解其系统资源瓶颈 ------------------------------------------------------------------------------------------------------------------ ### 1.压pod: HPA:启动镜像: ``` [root@k8smaster ~]# kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01;do wget -q -O- http://10.244.249.32:8000; done" ``` 另开一个窗口看: ``` [root@k8smaster ~]# kubectl get hpa jd-web-deployment --watch NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE jd-web-deployment Deployment/jd-web-deployment 4%/50% 20 40 20 8m35s ``` (目前效果不是很明显,官方网站的例子明显) ### 2.压web服务(观察监控(promethues和dashboard)): ab命令访问: ab命令访问 访问web:192.168.2.7:30001 或者因为有ingress负载均衡,可以直接访问www.jdweb.com 并且打开prometheus和dashboard 四种方式观察 kubectl top pod http://192.168.2.7:30003/targets http://192.168.2.7:30529 https://192.168.2.7:30537 ``` [root@nfs ~]# yum install httpd-tools -y ``` 1000个请求,10并发数 ab -n 1000 -c 10 -g output.dat www.jdweb.com -t 60 在60秒内发送尽可能多的请求 ``` [root@nfs ~]# ab -n 1000000 -c 1000 -g output.dat http://www.jdweb.com/sd/disk This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking www.jdweb.com (be patient) ``` ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/%E6%B5%8B%E8%AF%95%E5%89%8D.jpg) ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/%E5%8E%8B%E6%B5%8B%E5%89%8D2.jpg) ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/100w%E8%AF%B7%E6%B1%82+10%E5%B9%B6%E5%8F%91.jpg) 十一.构建CI/CD环境,安装gitlab、Jenkins、Harbor实现相关的代码发布、镜像制作、数据备份等流水线工作(待完善) ------------------------------------------------------------------------------------------------------------------ ![输入图片说明](%E6%95%88%E6%9E%9C%E5%9B%BE/cicd.png) ### 1.Harbor上面已经部署好 ### 2.部署Gitlab([https://gitlab.cn/install](https://gitlab.cn/install)) ``` [root@gitlab ~]# mkdir gitlab cd gitlab/ sudo yum install -y curl policycoreutils-python openssh-server perl curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash sudo yum install gitlab-jh sudo gitlab-ctl reconfigure [root@gitlab ~]# cat /etc/gitlab/initial_root_password # WARNING: This value is valid only in the following conditions # 1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run). # 2. Password hasn't been changed manually, either via UI or via command line. # # If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password. Password: scTECH1qkagnwaxWioBVHzhfi5M27gpr7HlrYXn+u40= # NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours. ``` 访问192.168.1.130(遇到问题,访问超时502)消耗的内存太大,使实验做不下去,目前暂停,随时开启 ### 3.Jenkins 在 Kubernetes 中部署jenkins #### 3.1 各节点拉取镜像: docker pull jenkinsci/blueocean #### 3.2 创建命名空间devops-tools ``` [root@k8smaster jenkins]# kubectl apply -f namespace.yaml namespace/devops-tools created [root@k8smaster jenkins]# kubectl get ns NAME STATUS AGE default Active 7d4h devops-tools Active 6s ingress-nginx Active 4d23h kube-node-lease Active 7d4h kube-public Active 7d4h kube-system Active 7d4h kubernetes-dashboard Active 5d1h nfs Active 3d1h ``` #### 3.3 创建服务账号,集群绑定 jenkins-admin ``` [root@k8smaster jenkins]# kubectl apply -f serviceAccount.yaml clusterrole.rbac.authorization.k8s.io/jenkins-admin created serviceaccount/jenkins-admin created clusterrolebinding.rbac.authorization.k8s.io/jenkins-admin created ``` #### 3.4 修改volume.yaml中的values ```bash nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - k8snode2 ``` ``` [root@k8smaster jenkins]# vim volume.yaml [root@k8smaster jenkins]# kubectl apply -f volume.yaml storageclass.storage.k8s.io/local-storage created persistentvolume/jenkins-pv-volume created persistentvolumeclaim/jenkins-pv-claim created [root@k8smaster jenkins]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE jenkins-pv-volume 10Gi RWO Retain Bound devops-tools/jenkins-pv-claim local-storage 87s ``` #### 3.5 部署jenkins 注意资源限制 ``` [root@k8smaster jenkins]# kubectl apply -f deployment.yaml deployment.apps/jenkins created [root@k8smaster jenkins]# kubectl get deploy -n devops-tools NAME READY UP-TO-DATE AVAILABLE AGE jenkins 0/1 1 0 94s [root@k8smaster jenkins]# kubectl get pod -n devops-tools -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES jenkins-b8486f789-rsrsc 0/1 Running 3 7m4s 10.244.249.50 k8snode1 ``` 需要等几分钟READY变为1(等麻了) ``` [root@k8smaster jenkins]# kubectl get pod -n devops-tools -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES jenkins-8479c47cc9-49x5r 1/1 Running 30 10h 10.244.249.61 k8snode1 [root@k8smaster jenkins]# kubectl get deploy -n devops-tools -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR jenkins 1/1 1 1 10h jenkins jenkinsci/blueocean app=jenkins-server [root@k8smaster jenkins]# kubectl logs jenkins-7cc95544d-qnhxv -n devops-tools ``` #### 3.6 启动服务发布Jenkins的pod ``` [root@k8smaster jenkins]# kubectl apply -f service.yaml service/jenkins-service created [root@k8smaster jenkins]# kubectl get svc -n devops-tools NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE jenkins-service NodePort 10.111.178.148 8080:32000/TCP 15s [root@k8smaster jenkins]# ``` #### 3.7 访问192.168.2.7:32000 如何得到密码: 进入pod(别忘记接命名空间!!!) ``` [root@k8smaster jenkins]# kubectl exec -it -n devops-tools jenkins-8479c47cc9-49x5r -- bash bash-5.1$ cat /var/jenkins_home/secrets/initialAdminPassword 80a37742026741a2b2a0c9eb681112f2 bash-5.1$ exit exit [root@k8smaster jenkins]# ``` #### 3.8 Jenkins+BlueOcean+Pipeline图 进入之后,完成配置重启,稍等几分钟 ![输入图片说明](Jenkins+BlueOcean+Pipeline%E5%9B%BE/jenkins%E7%99%BB%E5%BD%95%E7%95%8C%E9%9D%A2.jpg) ![输入图片说明](Jenkins+BlueOcean+Pipeline%E5%9B%BE/%E6%B3%A8%E5%86%8C%E7%AE%A1%E7%90%86%E5%91%98%E8%B4%A6%E6%88%B7.jpg) ![输入图片说明](Jenkins+BlueOcean+Pipeline%E5%9B%BE/%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6.jpg) ![输入图片说明](Jenkins+BlueOcean+Pipeline%E5%9B%BE/%E9%97%AE%E9%A2%98%E4%B8%8D%E5%A4%A7.jpg) ![输入图片说明](Jenkins+BlueOcean+Pipeline%E5%9B%BE/%E5%AE%9E%E4%BE%8B%E9%85%8D%E7%BD%AE.jpg) ![输入图片说明](Jenkins+BlueOcean+Pipeline%E5%9B%BE/%E5%B7%A5%E4%BD%9C%E5%8F%B0.jpg) 关于装Jenkins的Gitee插件出现了问题,github又有网络问题(暂未解决) ![输入图片说明](Jenkins+BlueOcean+Pipeline%E5%9B%BE/%E4%B8%8B%E8%BD%BDgitee%E6%8F%92%E4%BB%B6.png) ---- ### 4.Helm v3安装jenkins(待完善) 给jenkins创建动态PVC卷 使用NFS 作为后端的存储,使用动态PV 的自动供给 为Jenkins持久化数据。部署NFS 服务( 192.168.2.12主机上 ) ``` mkdir -p /home/cicd [root@nfs ~]# echo "/home/cicd *(rw,sync,no_root_squash,no_subtree_check)" >> /etc/exports [root@nfs ~]# exportfs -arv exporting 192.168.2.0/24:/home/nfs exporting 192.168.2.0/24:/jd/web exporting *:/home/cicd ``` helm3部署Jenkins的国内资料较少,在k8s内部部署目前暂未做到 只能用war包或许在另外一台机器启动。 [https://www.jenkins.io/zh/doc/pipeline/tour/getting-started/](https://www.jenkins.io/zh/doc/pipeline/tour/getting-started/) ---- 十二.考虑日志收集解决方案融入(filebeat、kafka、zookeeper等) ------------------------------------------------------------------------------------------------------------------ 安装日志收集工具。选择适合的日志收集工具,例如Filebeat、Kafka和Zookeeper,并在相应节点上安装。 配置日志收集器。根据您的需求配置日志收集器,例如指定日志路径、设置过滤条件等。 将日志发送到中央存储。将收集到的日志发送到Kafka或其他中央存储,以便后续查询和分析。 # 项目心得 当我花费了很长时间,搭建并维护一个名为"k8s综合项目"的高可用、高性能web集群。这个项目基于Kubernetes和Docker环境,模拟了企业级生产环境,并使用了许多优秀的技术工具来实现自动化运维、负载均衡、数据备份等功能。 下面是我在该项目中所完成的主要任务: 规划设计整个集群的架构,部署防火墙、k8s单master的集群环境及相关服务器。 部署Ansible,实现相关软件的自动化运维工作以及防火墙服务器和堡垒机的部署。 制作并部署Web接口系统镜像到k8s里作为应用,采用HPA技术,根据CPU使用率进行水平扩缩,最小20个,最多40个pod。 部署nfs服务器,为整个web集群提供数据,让所有的web 业务pod都可以访问,通过pv和pvc、卷挂载实现。 使用探针(liveless、readiness、startup)的httpGet和exec方法对web业务pod进行监控,一旦出现问题马上重启,增强业务pod的可靠性。 启动MySQL的pod,为web业务提供数据库服务。 利用Prometheus和Grafana实现对K8S集群系统资源监控。 安装k8s的Dashboard对整个集群资源进行掌控了解。 使用ingress给web业务做负载均衡。 对k8s集群进行压力测试,了解其系统资源瓶颈。 构建CI/CD环境,安装GitLab、Jenkins和Harbor实现相关的代码发布、镜像制作、数据备份等流水线工作。 将日志收集解决方案融入。 这个项目是我在开发过程中所遇到的最具挑战性和最有成就感的项目之一。通过该项目,我不仅加深了对于Kubernetes、Docker、Ansible和Git等技术工具的理解和掌握,还进一步提升了我的自动化运维、负载均衡、数据备份等方面的技能。