Vmware虚拟机搭建 K8S Jenkins Gitlab Harbor Docker 一键部署SpringCloud微服务

发布时间:2023年12月30日

一.系统环境

本文主要基于Kubernetes1.22.2和Linux操作系统Ubuntu 20.04.6。

操作系统主机名IP地址进程功能
Ubuntu 20.04.6k8s-master192.168.189.128docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico主节点
Ubuntu 20.04.6k8s-node1192.168.189.129docker,kubelet,kube-proxy,calico从节点
Ubuntu 20.04.6k8s-node2192.168.189.130docker,kubelet,kube-proxy,calico从节点
Ubuntu 20.04.6gitlab192.168.189.131gitlab,doker,jenkinsgitlab,jenkins
Ubuntu 20.04.6harbor192.168.189.132docker,harborharbor

二.Kubernetes

2.1?概述

什么是Kubernetes?它的主要特点是什么?Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。 Kubernetes是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。其主要特点包括自动化部署、自我修复、水平扩展、服务发现和负载均衡等。

Kubernetes 为你提供的功能如下:

1.服务发现和负载均衡:Kubernetes 可以使用 DNS 名称或自己的 IP 地址来曝露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
2.存储编排:Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。
3.自动部署和回滚:你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态4更改为期望状态。 例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
4.自动完成装箱计算:你为 Kubernetes 提供许多节点组成的集群,在这个集群上运行容器化的任务。 你告诉 Kubernetes 每个容器需要多少 CPU 和内存 (RAM)。 Kubernetes 可以将这些容器按实际情况调度到你的节点上,以最佳方式利用你的资源。
5.自我修复:Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。
6.密钥与配置管理:Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

2.2Kubernetes 组件

Kubernetes 集群架构如下:

Kubernetes 集群组件如下:

请解释一下Kubernetes的架构和核心组件。 Kubernetes的架构包括Master节点和Node节点。核心组件包括kube-apiserver、etcd、kube-scheduler、kube-controller-manager、kubelet和kube-proxy等。

'''
1.kube-apiserver:
- kube-apiserver 是 Kubernetes 集群的 API 服务器,它是集群的控制面的入口点。它负责提供 RESTful API,以便其他组件和用户可以与集群进行交互。kube-apiserver 接收来自客户端和其他组件的请求,并将这些请求转换为内部操作,如创建、更新和删除资源对象。它还负责对这些请求进行身份验证、授权和准入控制。
2.etcd:
- etcd 是 Kubernetes 集群的分布式键值存储系统,用于存储集群的配置数据、状态信息和元数据。etcd 提供了高可用性、一致性和分布式锁等特性,使得 Kubernetes 集群可以在多个节点之间共享和同步数据。kube-apiserver、kube-scheduler、kube-controller-manager 等组件都会使用 etcd 来存储集群的状态信息和配置数据。
3.kube-scheduler:
- kube-scheduler 是 Kubernetes 集群中的调度器组件,它负责将新创建的 Pod 调度到集群中的节点上。kube-scheduler 会考虑诸多因素,如资源需求、节点的负载情况、亲和性和反亲和性规则等,来决定将 Pod 调度到哪个节点上。通过调度器的工作,可以实现资源的合理分配和负载均衡。
4.kube-controller-manager:
- kube-controller-manager 是 Kubernetes 集群中的控制器管理器组件,它包含了多个控制器,用于监控集群中的资源对象的状态,并根据需要进行调节和控制。比如,NodeController 负责监控节点的健康状态,ReplicationController 负责监控 Pod 副本的数量,EndpointController 负责更新服务的终端信息等。这些控制器协同工作,确保集群中的资源对象处于期望的状态。
5.kubelet:
- kubelet 是运行在每个节点上的代理组件,负责管理节点上的容器和 Pod。kubelet 接收来自 kube-apiserver 的 Pod 创建请求,然后根据这些请求在节点上创建和管理对应的 Pod。它还会监控节点上的容器和 Pod 的状态,并定期上报给 kube-apiserver。此外,kubelet 还会与容器运行时(如 Docker、containerd 等)交互,以确保容器的运行状态。
6.kube-proxy:
- kube-proxy 是 Kubernetes 集群中的网络代理组件,负责实现集群内部的服务发现和负载均衡。kube-proxy 会监听 kube-apiserver 中的服务和端点的变化,然后根据这些变化来更新节点上的网络规则,以确保服务的访问能够正确地转发到对应的 Pod 上。kube-proxy 还支持多种代理模式,如 iptables、IPVS 等。

node组件如下:

1.kubelet:kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。kubelet 接收一组通过各类机制提供给它的 PodSpecs, 确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。
2.kube-proxy:kube-proxy 是集群中每个节点(node)所上运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。kube-proxy 维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发。
1.什么是Pod?它的作用是什么?与容器的关系是什么? Pod是Kubernetes中最小的部署单元,它可以包含一个或多个容器。Pod提供了一个共享的网络和存储空间,容器在同一个Pod中共享这些资源。

2.什么是serveice,什么是ingress,他们的作用是啥,他们与Pod的关系是什么? 在 Kubernetes 中,Service 和 Ingress 都是用于管理集群中服务访问的资源对象,它们与 Pod 之间有着不同的关系和作用。
          Service:
- Service 是 Kubernetes 中的一种资源对象,用于定义一组具有相同功能的 Pod 的访问方式和网络策略。Service 提供了一种抽象机制,使得应用程序可以通过 Service 名称来访问后端 Pod,而不需要关心具体的 Pod 实例。Service 可以通过标签选择器来选择匹配的 Pod,并为这些 Pod 提供统一的访问入口,支持负载均衡和服务发现等功能。 
         Ingress:
- Ingress 是 Kubernetes 中的一种资源对象,用于定义集群中的 HTTP 和 HTTPS 路由规则,允许外部流量访问集群中的服务。Ingress 可以定义不同的路由规则,如域名、路径、TLS 加密等,以便将外部流量路由到集群中不同的服务。Ingress 的作用是实现集群的入口流量管理和路由。
与 Pod 的关系:
- Service 与 Pod 的关系:Service 通过标签选择器选择匹配的 Pod,并为这些 Pod 提供统一的访问入口。Service 可以将外部流量负载均衡到多个 Pod 上,实现了对后端 Pod 的访问和负载均衡。
- Ingress 与 Pod 的关系:Ingress 定义了外部流量如何访问集群中的服务,它可以将外部流量路由到后端的 Service 或 Pod 上。Ingress 通过定义路由规则,将外部流量导向不同的服务或 Pod,实现了集群的入口流量管理和路由。而 Ingress 负责定义集群的入口流量路由规则,将外部流量导向不同的服务或 Pod。这些资源对象共同协作,实现了集群中服务的访问管理和流量路由。

3.请解释一下Kubernetes中的控制器(Controller)的概念和作用。 控制器是Kubernetes中用于管理Pod副本数量和状态的组件,它包括ReplicaSet、Deployment、StatefulSet等。控制器负责确保集群中运行指定数量的Pod副本,并在Pod发生故障时进行自我修复。

4.什么是Kubelet?它在Kubernetes集群中的角色是什么? Kubelet是运行在每个Node节点上的代理,负责管理节点上的Pod和容器。它与Master节点通信,执行Pod的创建、启动、停止等操作。

5.请解释一下Kubernetes中的存储卷(Volume)的概念和作用。 存储卷是Kubernetes中用于持久化存储数据的抽象,它可以被挂载到Pod中的一个或多个容器中,提供了数据持久化和共享的功能。

6.什么是Namespace?什么是Label?.它的作用是什么? 在 Kubernetes 中,Namespace 和 Label 都是用于组织和标识集群中资源的重要概念,它们分别具有不同的作用和功能。
         Namespace:
- Namespace 是 Kubernetes 中用于将集群资源划分成多个虚拟集群的一种机制。它允许用户在集群中创建多个逻辑上相互隔离的工作单元,每个 Namespace 中可以包含一组相互关联的资源,如 Pod、Service、Deployment 等。Namespace 的主要作用是提供一种逻辑隔离和资源管理的机制,使得不同团队或应用程序可以在同一个集群中独立地使用资源而不会相互干扰。
         Label:
- Label 是 Kubernetes 中用于对资源对象进行标记和分类的一种机制。Label 是一组键值对的元数据,可以附加到各种资源对象上,如 Pod、Service、Deployment 等。Label 可以用于对资源进行分类、筛选和组织,以便于后续的查询、操作和管理。Label 的主要作用是提供一种灵活的方式来对资源对象进行分类和标记,使得用户可以根据标签的匹配关系对资源进行选择和操作。
作用:
- Namespace 的作用是提供了一种逻辑隔离和资源管理的机制,使得不同团队或应用程序可以在同一个集群中独立地使用资源而不会相互干扰。
- Label 的作用是提供了一种灵活的方式来对资源对象进行分类和标记,使得用户可以根据标签的匹配关系对资源进行选择和操作。Label 还可以用于实现资源的分组、关联和筛选,以便于后续的管理和操作。
因此,Namespace 提供了一种资源隔离和管理的机制,使得不同团队或应用程序可以在同一个集群中独立地使用资源;而 Label 则提供了一种灵活的方式对资源进行分类和标记,以便于后续的查询、操作和管理。这两个概念共同协作,为 Kubernetes 中的资源管理和组织提供了灵活和强大的机制。

1.请解释一下Kubernetes中的水平扩展(Horizontal Pod Autoscaler)的概念和作用。 水平扩展是Kubernetes中用于根据资源利用率自动调整Pod副本数量的功能,它可以根据CPU利用率或自定义指标来自动扩展或缩减Pod的数量。

2.如何在Kubernetes中进行应用程序的部署和更新? 可以使用Deployment来进行应用程序的部署和更新,通过定义Deployment对象,Kubernetes可以自动创建和管理Pod副本,并支持滚动更新。

3.请解释一下Kubernetes中的滚动更新(Rolling Update)的概念和原理。 滚动更新是Kubernetes中用于无缝更新应用程序的机制,它通过逐步替换旧版本的Pod副本来实现应用程序的更新,确保应用程序在更新过程中保持可用性。

4.什么是Kubernetes中的健康检查(Liveness Probe)和就绪检查(Readiness Probe)? 健康检查用于检测容器是否处于健康状态,就绪检查用于检测容器是否已经准备好接收流量。它们可以通过HTTP请求、TCP连接或命令执行等方式进行检查。

5.如何进行Kubernetes集群的故障排除和调试? 可以通过查看日志、执行命令、使用调试工具、检查事件和状态等方式进行故障排除和调试。

6.什么是Deployment?用于部署无状态的服务,这个最常用的控制器。一般用于管理维护企业内部无状态的微服务,比如configserver、zuul、springboot。他可以管理多个副本的Pod实现无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等功能。

7.有状态和无状态的区别:
无状态
(1)、是指该服务运行的实例不会在本地存储需要持久化的数据,并且多个实例对于同一个请求响应的结果是完全一致的。
(2)、多个实例可以共享相同的持久化数据。例如:nginx实例,tomcat实例等
(3)、相关的k8s资源有:ReplicaSet、ReplicationController、Deployment等,由于是无状态服务,所以这些控制器创建的pod序号都是随机值。并且在缩容的时候并不会明确缩容某一个pod,而是随机的,因为所有实例得到的返回值都是一样,所以缩容任何一个pod都可以 
有状态
(1)、宠物和牛的类比,农场主的牛如果病了可以丢掉再重新买一头,如果宠物主的宠物病死了是没法找到一头一模一样的宠物的。
有状态服务 可以说是 需要数据存储功能的服务、或者指多线程类型的服务,队列等。(mysql数据库、kafka、zookeeper等)
(2)、每个实例都需要有自己独立的持久化存储,并且在k8s中是通过申明模板来进行定义。持久卷申明模板在创建pod之前创建,绑定到pod中,模板可以定义多个。
说明
(1)、有状态的 pod是用来运行有状态应用的,所以其在数据卷上存储的数据非常重要,在 Statefulset缩容时删除这个声明将是灾难性的,特别是对于 Statefulset来说,缩容就像减少其 replicas 数值一样简单。基于这个原因,当你需要释放特定的持久卷时,需要手动删除对应的持久卷声明。
(2)、相关的k8s资源为:statefulSet,由于是有状态的服务,所以每个pod都有特定的名称和网络标识。比如pod名是由statefulSet名+有序的数字组成(0、1、2..)
(3)、在进行缩容操作的时候,可以明确知道会缩容哪一个pod,从数字最大的开始。并且Stat巳fulset 在有实例不健康的情况下是不允许做缩容操作的。
StatefulSet 缩容任何时候只会操作 一个 pod 实例,所以有状态应用的缩容不会很迅速。举例来说, 一个分布式存储应用若同时下线多个节点 ,则可能导致其数据丢失 。 比如说一个数据项副本数设置为 2 的数据存储应用, 若 同时有两个节点下线,一份数据记录就会丢失,如果它正好保存在这两个节点上 。 若缩容是线性的 ,则分布式存储应用就有时间把丢失的副本复制到其他节点 ,保证数据不会丢失。

存储:
1、PV、PVC是什么?
PersistentVolume(PV)是群集中的一块存储,可以是NFS、iSCSI、本地存储等,由管理员配置或使用存储类动态配置。 PV定义了存储的容量、访问模式、持久化存储的类型等属性。PV的生命周期是独立于Pod的,即使Pod被删除,PV仍然存在,可以被其他Pod继续使用。
PersistentVolumeClaim(PVC)是一个持久化存储卷,我们在创建pod时可以定义PVC类型的存储卷,PVC可以用来访问各种类型的持久化存储,如本地存储、网络存储、云存储等,而不必关心这些资源的实际位置和类型,PVC的使用可以使应用程序更加灵活和可移植,同时也可以提高存储资源的利用率。
PVC和PV它们是一一对应的关系,PV如果被PVC绑定了,就不能被其他PVC使用了。
2、PV的供应方式
两种分别为静态、动态:

静态供应:管理员手动创建PV对象,并将其绑定到一个具体的存储后端上,然后Pod可以通过PVC(Persistent Volume Claim)请求绑定到该PV上。
动态供应:管理员通过StorageClass定义一组存储后端,然后Pod可以通过PVC请求绑定到该StorageClass上,K8s会自动创建一个PV对象并将其绑定到一个可用的存储后端上。
3、PV、PVC的回收策略
当我们创建pod时如果使用pvc做为存储卷,那么它会和pv绑定,当删除pod,pvc和pv绑定就会解除,解除之后和pvc绑定的pv卷里的数据需要怎么处理 有以下几种:

Kubernetes中有三种PV回收策略:

Retain:保留PV,但不删除底层存储资源。这意味着PV中的数据仍然存在,但需要手动清理。
Delete:删除PV和底层存储资源。这意味着PV中的数据将被永久删除。
Recycle:删除PV中的数据,但不删除底层存储资源。这意味着PV中的数据将被清除,但底层存储资源可以重新使用。(不推荐,1.15可能被移除)
Kubernetes中有两种PVC回收策略:

Retain:保留PVC,但不删除底层存储资源。这意味着PVC中的数据仍然存在,但需要手动清理。
Delete:删除PVC和底层存储资源。这意味着PVC中的数据将被永久删除。
需要注意的是,PVC的回收策略必须与其所绑定的PV的回收策略相匹配。例如,如果PV的回收策略为Retain,则PVC的回收策略也必须为Retain。否则,可能会导致数据丢失或存储资源泄漏。
如果删除pvc不删除pv,重新创建同样的pvc,那么pvc状态会处于Pending状态,因为pv的当前状态为Released。这也和上面定义的回收策略息息相关。

ConfigMap配置中心理论知识
ConfigMap是API对象,用于存放明文(非机密性)数据保存到键值对中,可以使用环境变量、命令行参数或者存储卷方式应用到Pod中,ConfigMap相当于Pod中程序的配置文件,通过修改ConfigMap内容来修改程序的配置。
ConfigMap在设计上不是用来存储大量数据的,所以在ConfigMap中保存的数据不能超过1MiB。
二、创建ConfigMap的四种方式
1、第一种:通过命令行创建ConfigMap
2、第二种:通过指定文件创建ConfigMap
3、第三种:通过指定目录创建ConfigMap
4、第四种:通过YAML资源清单创建ConfigMap
三、使用ConfigMap的三种方式
1、第一种:使用环境变量引入-configMapKeyRef方式
2、第二种:使用环境变量引入-envfrom方式
3、第三种:使用volume卷挂载
ConfigMap编辑并保存后对于卷挂载方式,支持热加载(大约等10s)生效,会更新到容器配置中,但对于变量方式并不支持,需要重新删除创建,更改的数据才会生效。
configMapKeyRef和envfrom方式引入变量区别?

configMapKeyRef是一种将ConfigMap中的数据作为环境变量注入到容器中的方式。它允许你在Pod的定义中引用ConfigMap中的特定键值对,并将其作为环境变量传递给容器。这种方式适用于将ConfigMap中的配置数据直接暴露给容器内的应用程序。
envFrom是一种将整个ConfigMap的数据作为环境变量注入到容器中的方式。它允许你在Pod的定义中引用一个或多个ConfigMap,并将它们的所有键值对作为环境变量传递给容器。这种方式适用于将多个相关的配置数据一次性注入到容器内。


ConfigMap:用于存放文明非加密配置信息。
Secret:用于存放加密数据,比如密码、token等信息。
Secret三种可选参数:
generic:通用类型,常于存储密码数据。
tls:用于存储私钥和证书。
docker-registry:用于存放docker仓库的认证信息。
Secret三种类型:
Service Account:用于被 serviceaccount 引用。serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。
Opaque:base64编码格式的Secret,用来存储密码、秘钥等。可以通过base64 --decode解码获得原始数据,因此安全性弱
kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息

三.配置节点的基本环境?

先配置节点的基本环境,5个节点都要同时设置,在此以k8master作为示例。

强制更改时区为上海
ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
bash -c "echo 'Asia/Shanghai' > /etc/timezone"
禁用swap(如果不关闭swap,就会在kubeadm初始化Kubernetes的时候报错)
swapoff -a ;sed -i '/swap/d' /etc/fstab
关闭防火墙。
ufw disable

ssh-keygen ?(三台k8s配置免密)
ssh-copy-id 192.168.189.128 (分别copy到对方)

查看Ubuntu系统版本

cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"

首先设置主机名,执行完下面修改主机名后每个节点都要bash一下

hostnamectl set-hostname master?
hostnamectl set-hostname node1
hostnamectl set-hostname node2
hostnamectl set-hostname gitlab (gitlab和jenkins共用)
hostnamectl set-hostname harbor

root@master:~# cat /etc/hostname?
master

配置5个节点静态IP地址(本次实验使用的是vmware NAT模式)

cat /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
? ethernets:
? ? ens33:
? ? ? dhcp4: false
? ? ? optional: true
? ? ? addresses: [192.168.189.129/24]
? ? ? gateway4: 192.168.189.2
? ? ? nameservers:
? ? ? ? addresses: [192.168.111.2,114.114.114.114] #修改dns为自己网络环境中的地址

? version: 2

使配置生效

netplan apply ?

测试机器是否可以访问网络?

ping www.baidu.com

PING www.baidu.com (14.215.177.39) 56(84) bytes of data. 64 bytes from www.baidu.com (14.215.177.39): icmp_seq=1 ttl=128 time=48.0 ms 64 bytes from www.baidu.com (14.215.177.39): icmp_seq=2 ttl=128 time=52.9 ms 64 bytes from www.baidu.com (14.215.177.39): icmp_seq=3 ttl=128 time=39.8 ms ^C --- www.baidu.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2009ms rtt min/avg/max/mdev = 39.843/46.940/52.968/5.417 ms

配置IP地址和主机名映射k8s三台添加host

cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 root

# The following lines are desirable for IPv6 capable hosts
::1 ? ? ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.189.128 master
192.168.189.129 node1
192.168.189.130 node2


配置Ubuntu软件源,软件源如下,最后三行是k8s源

cat /etc/apt/sources.list
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu focal stable
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main

apt-key.gpg是k8s的deb源公钥,加载k8s的deb源公钥命令为:

curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg |sudo apt-key add -
apt-get update

四.节点安装docker,并进行相关配置

k8s是容器编排工具,需要容器管理工具,所以三个节点同时安装docker,其他两台因为因为gitlab和harbor是docker跑,看个人需求

添加docker源:

curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

apt-get install docker-ce

设置docker开机自启动并现在启动docker。

systemctl enable docker --now

注意kubernetes V1.22.2版本及其以后,要求容器的cgroup driver 为systemd,但是docker默认的cgroup driver 是cgroupfs,kubernetes 1.21版本及其之前,是不需要修改cgroup driver的。

配置docker镜像加速器,并设置docker的cgroup driver 为systemd。

cat /etc/docker/daemon.json?
{
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}

systemctl restart docker

docker info | grep -i cgroup :这时Cgroup Driver就变为systemd了。

设置iptables不对bridge的数据进行处理,启用IP路由转发功能。
cat /etc/sysctl.d/k8s.conf?
net.bridge.bridge-nf-call-ip6tables = 1?
net.bridge.bridge-nf-call-iptables = 1?
net.ipv4.ip_forward = 1?
使配置生效
sysctl -p /etc/sysctl.d/k8s.conf


五.安装kubelet,kubeadm,kubectl

三个节点都安装kubelet,kubeadm,kubectl,以k8smaster为例:?

Kubelet 是 kubernetes 工作节点上的一个代理组件,运行在每个节点上
Kubeadm 是一个快捷搭建kubernetes(k8s)的安装工具,它提供了 kubeadm init 以及 kubeadm join 这两个命令来快速创建 kubernetes 集群,kubeadm 通过执行必要的操作来启动和运行一个最小可用的集群
kubectl是Kubernetes集群的命令行工具,通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署

apt-get -y install kubelet=1.22.2-00 kubeadm=1.22.2-00 kubectl=1.22.2-00
设置kubelet开机自启动并现在启动kubelet。
systemctl enable kubelet --now
kubeadm初始化
apt update三台
master执行:
kubeadm init --apiserver-advertise-address=192.168.189.128 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.22.2 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

两个node执行:(使用上面生成的内容)
kubeadm join 192.168.189.128:6443 --token ju8p1y.8gjm5q00l6u5y1rp \
? ? ? ? --discovery-token-ca-cert-hash sha256:3f401b6187ed44ff8f4b50aa6453cf3eacc3b86d6a72e3bf2caba02556cb918e?
如果加入集群的token忘了,可以使用如下的命令获取最新的加入命令token。
kubeadm token create --print-join-command

六.部署CNI网络插件calico

master执行:kubectl get nodes
可以看到两个worker节点都加入到了k8s集群,此时三个节点的状态都是NotReady的,原因是没有CNI网络插件
为了节点间的通信,需要安装cni网络插件
现在去官网下载calico.yaml文件:

官网:https://projectcalico.docs.tigera.io/about/about-calico
curl https://docs.projectcalico.org/manifests/calico.yaml -O
查看镜像:
grep image calico.yaml
? ? ? ? ? image: docker.io/calico/cni:v3.26.1
? ? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? ? image: docker.io/calico/cni:v3.26.1
? ? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? ? image: docker.io/calico/node:v3.26.1
? ? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? ? image: docker.io/calico/node:v3.26.1
? ? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? ? image: docker.io/calico/kube-controllers:v3.26.1
? ? ? ? ? imagePullPolicy: IfNotPresent

k8s 三个节点都下载:

docker pull docker.io/calico/kube-controllers:v3.26.1

docker pull?docker.io/calico/cni:v3.26.1
docker pull docker.io/calico/node:v3.26.1

此时三个节点都有calico镜像了

master修改calico.yaml 文件,CALICO_IPV4POOL_CIDR的IP段要和kubeadm初始化时候的pod网段一致,注意格式要对齐,不然会报错。

cat calico.yaml | egrep "CALICO_IPV4POOL_CIDR|"10.244"" 
- name: CALICO_IPV4POOL_CIDR 
  value: "10.244.0.0/16"

kubectl apply -f calico.yaml

kubectl get pod -A | grep calico

kubectl get node

此时发现三个节点都是Ready状态了。

七.配置kubectl命令tab键自动补全

查看kubectl自动补全命令。
?

kubectl --help | grep bash

cat /etc/profile | head -3 # /etc/profile: system-wide .profile file for the Bourne shell (sh(1)) # and Bourne compatible shells (bash(1), ksh(1), ash(1), ...). source <(kubectl completion bash)

source /etc/profile

八.svc负载均衡修改

service的底层实现主要有两种方式,iptables和ipvs两种网络模式,决定了流量如何转发

Iptables模式和IPVS模式对比:

  • iptables:灵活、功能强大;规则遍历匹配和更新,呈线性时延
  • IPVS:工作在内核态,有更好的性能;调度算法丰富:rr,wrr,lc,wlc,ip hash…
  • 使用此种模式需要手动去修改,因为默认是iptables模式。不同的k8s集群搭建方式,其修改方式不同。
  1. kubeadm方式修改ipvs模式:
    第一步:修改配置文kube-proxy件参数。
    kubectl edit configmap kube-proxy -n kube-system...
    mode: “ipvs“
    ...
    第二步:删除该组Pod,重建所有节点。
    kubectl delete pod kube-proxy-btz4p -n kube-system
    
    • 注意事项:
    1. kube-proxy配置文件以configmap方式挂载存储。
    2. 如果让所有节点生效,需要重建所有节点kube-proxy pod
  2. 二进制方式修改ipvs模式:
    第一步:编辑修改配置文件。
    vi kube-proxy-config.yml 
    mode: ipvs
    ipvs:scheduler: "rr“
    第二步:重启kube-proxy。
    systemctl restart kube-proxy

?

1.查看配置文件位置。

[root@k8s-master bck]# kubectl  get configmap -n kube-system

?

2.在线编辑kube-proxy文件,修改参数为ipvs模式。

[root@k8s-master bck]# kubectl edit configmaps kube-proxy -n kube-system

?

?

3.此时需要删除这组pod重建,相当于重启。我这里只删除了一个节点,是为了验证对比效果,正常情况下是要重启所有节点的。

[root@k8s-master bck]# kubectl  delete pod kube-proxy-vkfkh -n kube-system

?4.在删除的kube-proxy容器所在节点上验证,我这里删除的是node2节点上的kube-proxy,重启后ipvs模式生效;node1节点没有删除,也就没有重启,依然还是iptables模式。使用ipvs模式验证需要安装ipvsadm。

三台机器安装ipvs

apt -y install ipvsadm ipset sysstat conntrack

ipvsadm -L 查看流量转发

cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_lc
modprobe -- ip_vs_lblc
modprobe -- ip_vs_lblcr
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- ip_vs_dh
modprobe -- ip_vs_fo
modprobe -- ip_vs_nq
modprobe -- ip_vs_sed
modprobe -- ip_vs_ftp
modprobe -- ip_vs_sh
modprobe -- ip_tables
modprobe -- ip_set
modprobe -- ipt_set
modprobe -- ipt_rpfilter
modprobe -- ipt_REJECT
modprobe -- ipip
modprobe -- xt_set
modprobe -- br_netfilter
modprobe -- nf_conntrack
EOF
chmod +x /etc/sysconfig/modules/ipvs.modules
/bin/bash /etc/sysconfig/modules/ipvs.modules
lsmod | grep -e ip_vs -e nf_conntrack_ipv4

九.gitlab安装

安装docker-compose

curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

mkdir?/data/gitlab

gitlab安装yaml

cat docker-compose.yml?
version: '3.1'
services:
? gitlab:
? ? image: 'gitlab/gitlab-ce:13.0.14-ce.0'
? ? container_name: 'gitlab'
? ? restart: always
? ? privileged: true
? ? hostname: '192.168.189.131'
? ? environment:
? ? ? TZ: 'Asia/Shanghai'
? ? ? GITLAB_OMNIBUS_CONFIG: |
? ? ? ? external_url 'http://192.168.189.131' # http协议所使用的访问地址,不加端口默认80
? ? ? ? gitlab_rails['time_zone']= 'Asia/Shanghai'
? ? ? ? gitlab_rails['smtp_enable'] = true
? ? ? ? gitlab_rails['gitlab_shell_ssh_port'] = 1222 # 此端口是run时22端口映射的1222端口
? ? ports:
? ? - '80:80'
? ? - '1222:22'
? ? volumes:
? ? - '/data/gitlab/config:/etc/gitlab'
? ? - '/data/gitlab/data:/var/opt/gitlab'
? ? - '/data/gitlab/logs:/var/log/gitlab'
docker-compose up -d 执行会去拉取镜像等待几分钟后即可访问

上面执行过程中,使用下面命令获取初始用户root的密码

docker exec -it $(docker ps | grep gitlab | awk '{print $1}') grep 'Password:' /etc/gitlab/initial_root_password

http://192.168.189.131/users/sign_in?

输入root和密码,会让你创建新密码

十.安装Jenkins

Jenkins是一个Java应用程序,需要在系统上安装Java 8或更高版本。我们将安装OpenJDK 11, Java平台的开源实现。

?apt update sudo apt install openjdk-11-jdk

java -version

使用以下wget命令导入Jenkins存储库的GPG键:

wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -

接下来,使用以下命令将Jenkins存储库添加到系统中:

sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'

启用Jenkins存储库后,通过输入以下命令更新apt包列表并安装最新版本的Jenkins:

sudo apt-get update sudo apt-get install jenkins

如果你得到一个错误消息(没有报错请忽略):

W: GPG 错误:https://pkg.jenkins.io/debian-stable binary/ Release: 由于没有公钥,无法验证下列签名:NO_PUBKEY 9B7D32F2D50582E6 E: 仓库 “http://pkg.jenkins.io/debian-stable binary/ Release” 没有数字签名。

解决方法

导入密钥:密钥报错里面就有

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9B7D32F2D50582E6

然后再次运行:

sudo apt-get update sudo apt-get install jenkins

Jenkins服务将在安装过程完成后自动启动。您可以通过如下命令来验证:

systemctl status jenkins

登录jenkins

http://192.168.189.131:8080/

cat /var/lib/jenkins/secrets/initialAdminPassword

从终端复制密码,粘贴到“管理员密码”域中,点击“继续”。

?通过单击“保存并完成”按钮来确认URL,设置过程将完成。

单击重启开始使用Jenkins按钮,您将被重定向到以您在前面的步骤之一中创建的admin用户身份登录的Jenkins仪表板。

十一.harbor 安装

#下载harbor
?

[root@harbor ~]# wget https://github.com/goharbor/harbor/releases/download/v2.8.2/harbor-offline-installer-v2.8.2.tgz

#解压 [root@harbor ~]# tar xf harbor-offline-installer-v2.8.2.tgz -C ./ #复制一份配置文件 [root@harbor ~]# cd harbor

[root@harbor harbor]# cp harbor.yml.tmpl harbor.yml

#修改配置文件

[root@harbor harbor]#vim harbor.yml

hostname: 192.168.189.132 #指定Harbor主机地址

#https: #注释这一行,这一行是https访问?式(需要证书才可以使?)

#port: 443 #注释这一行

#certificate: /your/certificate/path #注释证书?件

#private_key: /your/private/key/path #注释证书?件

harbor_admin_password: asdqwe123 #设置访问密码,可自行修改

systemctl enable --now docker

[root@harbor harbor]# ./prepare

[root@harbor harbor]# ./install.sh?--with-chartmuseum 
..... ? ----Harbor has been installed and started successfully.---- #成功即可

#验证运?情况

[root@harbor ~]# docker ps

访问harbor

十二.Jenkins基于https的k8s配置

jenkins 连接低版本的k8s时,不需要验证。但是新版本的启用了https和角色管理

安装中文语言包:(从箭头处搜索)安装需要的插件完事一块重启省得麻烦

安装kubernetes

重新登录jenkins,返回首页。

新建云:下面的公钥和凭据看下面

这步很重要也容易出错:

根据以上的配置,可以看到,已经是启用https了,这里就涉及到了密钥的问题

创建admin证书:
?

#1、查看kubernetes的config文件
cat ~/.kube/config
#2、根据配置文件生成证书.替换引号内部的信息为config内相关value(替换成上面)可以看下面的图

echo "certificate-authority-data" | base64 -d > ca.crt
echo "client-certificate-data" | base64 -d > client.crt #对应上面的值
echo "client-key-data" | base64 -d > client.key
#3、生成jenkins使用的cert.pfx,此处需要设置一个4位数以上的密码记住这个密码
openssl pkcs12 -export -out cert.pfx -inkey client.key -in client.crt -certfile ca.crt
ls
ca.crt cert.pfx client.key client.crt

把cert.pfx下载到本地

类型要改成上面的,把pfx文件导入,密码填干才设置的密码

连接测试ok添加jenkins地址保存

十三.gitlab和Jenkins 持续集成

创建test项目:

创建Jenkins用户

我这里设置的是adsqwe123

添加Jenkins公钥:

我这里是在项目里面添加例如test:

root@gitlab:~# cat .ssh/id_rsa.pub?
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC8pegIqtuQfSqGlQoTiZJ8TukoPLj4GK3RHXg81dHiABucqYzVkfMMnxlSdevZ0+dn4SQ+P7rdlPlyS5vtn2rMeKafDnKAU5mwRv+R4jpD1oEO4+0MzBvAzGrOSXxldpHvWbzamq7Xnhi01uIadVXQpluqOgx3AdSCB2fCbVAEWbPwwA40jZ9tA4UeoEJAQESKca+a1Qs9fNShFt4yvVhuSTgEuEr0q4jAeKk5S6BJ+ppsKNEl9LL51ZhfBgM6HkAlbTaIK4PcwMdf7hBou90RDj1BvCJn9Md2jhh7mXut04daXYfdyIPZymu8ueGYuKkmrQq0W0mSiFJEuluTpYY1tklP5XGnIOInfw3DPMGECu3p8GPoyj/OICiKsCrf8rTUIt6Vl6tHT8pl4fDtADC/ARDFQgLrkJBbfZKa6Fld/QNdUtJOM8GPyUgHwrD/ihb5uYW2gU9nKJTiSdzjRHGr+pZwdXPzV0H7xDrhvT/5upV7uxzBlI7bX2uEaRhNEOU= root@gitlab


复制进去添加

后续有新项目需要到Deploy Keys里面,在私人访问那里点启动就会到启用部署键这里

点击左侧的Access?Tokens,输入用户?jenkins,勾选权限,点击创建

test项目添加用户和相应权限

由于?jenkins安装时,勾选了推荐安装的插件,因此包含了git插件。

现在只需要安装gitlab插件即可

重启后添加gitlab地址

设置Git插件的全局配置,然后点击最下面的保存

创建Jenkins job

我这里用的是前面gitlab创建的jenkins用户和密码

选择“构建触发器”,勾选“Pull SCM”,这个选项会每隔一段时间检查一下GitLab仓库中代码是否有更新,有的话就执行构建操作。日程表如何设置,在这个输入框下面有说明。

mkdir /workjob
chmod 777 /workjob

其中?WORKSPACE?表示,下载git项目后的路径。

由于git项目为test,因此路径为:/var/lib/jenkins/workspace/test

点击保存

登录Jenkins服务器查看ok:

十四.jenkins配置maven

下载maven:

wget https://archive.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz

tar zxvf apache-maven-3.3.9-bin.tar.gz?

mv apache-maven-3.3.9 /usr/local/
cat /etc/profile

HISTFILESIZE=3000
HISTSIZE=3000
export HISTTIMEFORMAT="%F %T"

export JAVA_HOME=/usr? #前面安装Jenkins已经使用openjdk11所以位置是这样,将 JAVA_HOME 设置为 Java 的安装目录,而不是 Java 可执行文件的路径
export CLASSPATH=.:$JAVA_HOME/lib
export JAVA_HOME CLASSPATH PATH
export TMOUT=1800
export JRE_HOME=${JAVA_HOME}/jre
export PATH=${JAVA_HOME}/bin:${PATH}
export CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jart
export M2_HOME=/usr/local/apache-maven-3.3.9
export PATH=$M2_HOME/bin:$PATH

没有docker就去插件里面安装后在添加

十五.gitlab创建maven项目

?
首先从github上面,找一个基于maven的项目,地址如下:

https://github.com/solochen84/SpringBootDemo

使用git客户端,下载此项目代码

root@gitlab:/data/gitlab

git clone?https://github.com/solochen84/SpringBootDemo.git

?

?
将github下载的代码,提交到刚刚创建的项目中。效果如下:

把干才clone的目录 mv?springbootdemo?springbootdemo.bak

git clone?http://192.168.189.131/root/springbootdemo.git

cd? springbootdemo

mv?springbootdemo.bak/*? .

修改Dockerfile

cat Dockerfile?
FROM openjdk:8u342-jdk
ARG app
ADD $app app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

rm?-rf??kube.yaml?删除这个文件

?

创建新的k8s文件,具体详细信息最后有讲解

cat nginxtomcat.yaml?
apiVersion: v1
kind: Namespace
metadata:
? name: dev
#创建命名空间dev
---
apiVersion: v1
kind: ConfigMap
metadata:
? name: nginx-config
? namespace: dev
data: #ConfigMap挂载配置文件
? nginx.conf: |
? ? user ?nginx;
? ? worker_processes ?auto;
? ? error_log ?/var/log/nginx/nginx-error.log notice;
? ? pid ? ? ? ?/var/run/nginx.pid;
? ??
? ??
? ? events {
? ? ? ? worker_connections ?1024;
? ? }
? ??
? ??
? ? http {
? ? ? ? include ? ? ? /etc/nginx/mime.types;
? ? ? ? default_type ?application/octet-stream;
? ? ? ? log_format ?main ?'$remote_addr - $remote_user [$time_local] "$request" '
? ? ? ? ? ? ? ? ? ? ? ? ? '$status $body_bytes_sent "$http_referer" '
? ? ? ? ? ? ? ? ? ? ? ? ? '"$http_user_agent" "$http_x_forwarded_for"';
? ? ? ? access_log ?/var/log/nginx/access.log ?main;
? ? ? ? sendfile ? ? ? ?on;
? ? ? ? keepalive_timeout ?65;
? ? ? ? include /etc/nginx/conf.d/*.conf;
? ? }
---
apiVersion: v1
kind: PersistentVolume
metadata: ? #创建nginx pv 指定大小1G
? name: nginx-pv
? namespace: dev
spec:
? capacity:
? ? storage: 1Gi
? accessModes:
? ? - ReadWriteMany
? nfs:
? ? server: 192.168.189.132
? ? path: /var/nfsdata/nginx

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata: ? #创建pvc
? name: nginx-pvc
? namespace: dev
spec:
? storageClassName: ""
? volumeName: nginx-pv
? accessModes:
? ? - ReadWriteMany
? resources:
? ? requests:
? ? ? storage: 1Gi
? selector:
? ? matchLabels:
? ? ? type: nginx

---
apiVersion: v1
kind: PersistentVolume
metadata: ?#创建tomcat pv 指定大小1G
? name: tomcat-pv
? namespace: dev
spec:
? capacity:
? ? storage: 1Gi
? accessModes:
? ? - ReadWriteMany
? nfs:
? ? server: 192.168.189.132
? ? path: /var/nfsdata/tomcat

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
? name: tomcat-pvc
? namespace: dev
spec:
? storageClassName: ""
? volumeName: tomcat-pv
? accessModes:
? ? - ReadWriteMany
? resources:
? ? requests:
? ? ? storage: 1Gi
? selector:
? ? matchLabels:
? ? ? type: tomcat

---
apiVersion: apps/v1
kind: Deployment
metadata: ?#nginx配置
? name: nginx-deployment
? namespace: dev
spec:
? replicas: 2
? selector:
? ? matchLabels:
? ? ? app: nginx-pod
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: nginx-pod
? ? spec:
? ? ? volumes:
? ? ? - name: nginx-config
? ? ? ? configMap:
? ? ? ? ? name: nginx-config
? ? ? - name: nfs-volume
? ? ? ? persistentVolumeClaim:
? ? ? ? ? claimName: nginx-pvc ?# 这里是NFS的PersistentVolumeClaim的名称
? ? ? containers:
? ? ? - name: nginx
? ? ? ? image: nginx:1.17.1
? ? ? ? ports:
? ? ? ? - containerPort: 80
? ? ? ? volumeMounts:
? ? ? ? - name: nginx-config
? ? ? ? ? mountPath: /etc/nginx/nginx.conf
? ? ? ? ? subPath: nginx.conf
? ? ? ? - name: nfs-volume
? ? ? ? ? mountPath: /usr/share/nginx/html ?# NGINX默认的静态资源文件目录
---
apiVersion: apps/v1
kind: Deployment
metadata:
? name: tomcat-deployment
? namespace: dev
spec:
? replicas: 2
? selector:
? ? matchLabels:
? ? ? app: tomcat-pod
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: tomcat-pod
? ? spec:
? ? ? imagePullSecrets:
? ? ? ? - name: harborsecret
? ? ? affinity:
? ? ? ? podAntiAffinity:
? ? ? ? ? requiredDuringSchedulingIgnoredDuringExecution:
? ? ? ? ? - labelSelector:
? ? ? ? ? ? ? matchExpressions:
? ? ? ? ? ? ? - key: app
? ? ? ? ? ? ? ? operator: In
? ? ? ? ? ? ? ? values:
? ? ? ? ? ? ? ? - tomcat-pod
? ? ? ? ? ? topologyKey: "kubernetes.io/hostname"
? ? ? volumes:
? ? ? - name: web-content
? ? ? ? persistentVolumeClaim:
? ? ? ? ? claimName: tomcat-pvc
? ? ? containers:
? ? ? - name: tomcat
? ? ? ? image: 192.168.189.132/java/tomcat:latest
? ? ? ? imagePullPolicy: Always
? ? ? ? ports:
? ? ? ? - containerPort: 8080
? ? ? ? volumeMounts:
? ? ? ? - name: web-content
? ? ? ? ? mountPath: /usr/local/tomcat/webapps/ROOT
---
apiVersion: networking.k8s.io/v1
#apiVersion: v1
kind: Ingress
metadata:
? name: my-ingress
? namespace: dev
? annotations:
? ? nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
? ingressClassName: nginx ? ? ?
? rules:
? ? - host: harbor.snow.com
? ? ? http:
? ? ? ? paths:
? ? ? ? ? - path: /(.*)
? ? ? ? ? ? pathType: ImplementationSpecific
? ? ? ? ? ? backend:
? ? ? ? ? ? ? service:
? ? ? ? ? ? ? ? name: nginx-service
? ? ? ? ? ? ? ? port:
? ? ? ? ? ? ? ? ? number: 80
? ? ? ? ? - path: /tomcat(/|$)(.*)
? ? ? ? ? ? pathType: ImplementationSpecific
? ? ? ? ? ? backend:
? ? ? ? ? ? ? service:
? ? ? ? ? ? ? ? name: tomcat-service
? ? ? ? ? ? ? ? port:
? ? ? ? ? ? ? ? ? number: 8080
---
apiVersion: v1
kind: Service
metadata:
? name: nginx-service
? namespace: dev
spec:
? selector:
? ? app: nginx-pod
? clusterIP: None
? type: ClusterIP
? ports:
? - port: 80
? ? targetPort: 80

---

apiVersion: v1
kind: Service
metadata:
? name: tomcat-service
? namespace: dev
spec:
? selector:
? ? app: tomcat-pod
? clusterIP: None
? type: ClusterIP
? ports:
? - port: 8080
? ? targetPort: 8080

#上传代码到我们的gitlab
git add .

git commit -m "xiangmu"

git push? #输入gitlab 账户密码比如 root? asdqwe123

上面的内容包括创建命名空间,前后端分离,副本数和反亲和性,使用nfs、ingress和harbor 仓库镜像

创建NFS服务端:这边是在harbor机器上搭建的

apt install -y nfs-kernel-server

mkdir -p?/var/nfsdata/nginx/? ?

mkdir -p?/var/nfsdata/tomcat/??

chmod -R 777 /var/nfsdata

systemctl restart nfs-kernel-server
exportfs -rv
k8s 三台机器安装nfs客户端然后挂载:
先要创建mkdir -p /var/nfsdata/nginx? 
       mkdir -p?/var/nfsdata/tomcat

apt install -y nfs-common

mount 192.168.189.132:/var/nfsdata/nginx /var/nfsdata/nginx
mount 192.168.189.132:/var/nfsdata/tomcat /var/nfsdata/tomcat

十六.harbor创建项目和用户

十七.jenkin修改默认用户

使用jenkins执行shell命令时,可能会出现权限不足的情况。

cat?/etc/default/jenkins

可以发现JENKINS_USER和JENKINS_GROUP变量的值是jenkins

为什么要和k8s master做ssh免密呢?因为jenkins需要登录到k8s master,做一些pod操作。

登录到jenkins服务器,生成秘钥
?

ssh-keygen

ssh-copy-id?192.168.189.128?

ssh?192.168.10.130 测试root免密

十八.jenkins登录harbor

Jenkins机器上:

cat /etc/docker/daemon.json
{"insecure-registries": ["192.168.189.132","y0qd3iq.mirror.aliyuncs.com"]}

systemctl restart docker?

测试登录:

?docker login 192.168.189.132 -u jenkins -p Aasdqwe123

十九.jenkins创建maven项目

登录到jenkins后台,点击?新建Item

输入名称,选择构建一个maven项目。注意:任务名称最好是项目名,因为下面的deploy_docker.sh脚本,会调用这个变量。

丢弃旧的构建,保留2天

输入仓库下载地址,选择用户root

输入maven构建命令:clean package

mvn clean package依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段。

package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库

build完成之后,选择执行shell命令

#!/bin/bash
jarName=spring-boot-demo-0.0.1-SNAPSHOT.jar
jarFolder=$JOB_NAME
harborPro=java
projectName=$JOB_NAME
docker_path=${WORKSPACE}
cp?${WORKSPACE}/target/${jarName}?${docker_path}
bash?-x?/root/docker_dir/deploy_docker.sh?${harborPro}?${projectName}?${docker_path}?${jarName}

jarName?jar包的文件名,名字随便

jarFolder?jar包的文件夹

harborPro?harbor里面的项目,在上面步骤中,创建java私有项目。

projectName?项目名,名字随便

docker_path?docker命令的工作目录

最后一步,会执行一个shell脚本。下面说到!

登录到jenkins服务器

root@gitlab:/workjob# cat deploy_docker.sh?
#!/bin/bash
# maven $workspace $jarname
# ${harborPro} ${projectName} ${docker_path} ${jarName}

set -e
harbor_project=$1
projectName=$2
docker_path=$3
appName=$4

# harbor认证用户
user_name=jenkins
password=Aasdqwe123

# harbor地址以及tag
tag=$(date +%s)
harbor_server=192.168.189.132
server_path=${harbor_server}
taget_image=${projectName}:${tag}
#${BUILD_NUMBER}
echo ${taget_image}

# 登录docker
cd ${docker_path}
docker login ${harbor_server} -u ${user_name} -p ${password}

# 生成镜像并推送到harbor,最后删除本地镜像
docker build --build-arg app=${appName} -t ${taget_image} .
docker tag ${taget_image} ${server_path}/${harbor_project}/${projectName}
echo "The name of image is ${server_path}/${harbor_project}/${projectName}"
docker push ${server_path}/${harbor_project}/${projectName}:latest
docker rmi -f $(docker images|grep ${projectName}|grep ${tag}|awk '{print $3}'|head -n 1)
chmod 755?deploy_docker.sh?

登录到k8s master,创建目录

mkdir /root/kube-conf

登录到jenkins服务器,新增重启应用脚本
?

root@gitlab:/workjob# cat reboot_app.sh?
#!/bin/bash
MASTER="192.168.189.128"
CONF_DIR="/root/kube-conf"

scp ${WORKSPACE}/*.yaml ${MASTER}:${CONF_DIR}
# Pod running process
RUN=$(ssh $MASTER kubectl get po -A |grep -w tomcat|wc -l)
if [ $RUN -eq 0 ];then
? ? ? ? ssh ${MASTER} kubectl apply -f ${CONF_DIR}/nginxtomcat.yaml
else
? ? ? ? # Delete pod
? ? ? ? podname=$(ssh ${MASTER} kubectl get po -A|grep -w tomcat|awk '{print $2}')
?? ?ns=$(ssh ${MASTER} kubectl get po -A|grep -w tomcat|awk '{print $1}')
?? ?ssh ${MASTER} kubectl delete po $podname --grace-period=0 --force -n $ns
?? ?ssh ${MASTER} kubectl apply -f ${CONF_DIR}/nginxtomcat.yaml
? ? ? ? #ssh ${MASTER} kubectl get po|grep ${ProJ}
fi
chmod 755?reboot_app.sh?

要使用 Harbor 作为 Kubernetes 集群的镜像仓库,你需要创建一个名为?harborsecret?的?imagePullSecrets,并将其与你的 Deployment 或 Pod 配置文件关联起来。

创建 Harbor 凭据: 使用以下命令创建一个 Docker 凭据,以便 Kubernetes 可以从 Harbor 拉取镜像:

kubectl create secret docker-registry harborsecret --docker-server=192.168.189.132 --docker-username=jenkins --docker-password=Aasdqwe123 --docker-email=jenkins@163.com

  1. 将凭据关联到 Deployment 或 Pod 配置文件中: 在你的 Deployment 或 Pod 配置文件中添加?imagePullSecrets?字段,将其值设置为之前创建的凭据名称?harborsecret,如下所示:具体在上方或者最下面详解yaml里面有

    spec:
      imagePullSecrets:
      - name: harborsecret

如果需要删除secret,使用命令

kubectl delete secrets harborsecret

保存

二十.访问k8s应用

root@k8s-master:~# kubectl get pods -o wide

如果发现pod运行在node服务器,状态是ImagePullBackOff

kubectl describe po maven-deployment-7bd87867f8-6tlgp -n dev

Get https://192.168.189.132/v2/: dial tcp 192.168.189.132:443: connect: connection refused

k8s-node?服务器的?/etc/docker/daemon.json?没有更改,两台都加这个

root@node1:/home/web# cat /etc/docker/daemon.json?
{
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": ["192.168.189.132"]
}
重新加载docker? ?
systemctl restart docker

二十一. ingress安装和构建java,并访问项目

由于网络问题,下载不便,所以直接用修改好的文件

root@master:/data/xiangmu/xx# cat deploy.yaml?
apiVersion: v1
kind: Namespace
metadata:
? name: ingress-nginx
? labels:
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx

---
# Source: ingress-nginx/templates/controller-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: controller
? name: ingress-nginx
? namespace: ingress-nginx
automountServiceAccountToken: true
---
# Source: ingress-nginx/templates/controller-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: controller
? name: ingress-nginx-controller
? namespace: ingress-nginx
data:
? allow-snippet-annotations: 'true'
---
# Source: ingress-nginx/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? name: ingress-nginx
rules:
? - apiGroups:
? ? ? - ''
? ? resources:
? ? ? - configmaps
? ? ? - endpoints
? ? ? - nodes
? ? ? - pods
? ? ? - secrets
? ? ? - namespaces
? ? verbs:
? ? ? - list
? ? ? - watch
? - apiGroups:
? ? ? - ''
? ? resources:
? ? ? - nodes
? ? verbs:
? ? ? - get
? - apiGroups:
? ? ? - ''
? ? resources:
? ? ? - services
? ? verbs:
? ? ? - get
? ? ? - list
? ? ? - watch
? - apiGroups:
? ? ? - networking.k8s.io
? ? resources:
? ? ? - ingresses
? ? verbs:
? ? ? - get
? ? ? - list
? ? ? - watch
? - apiGroups:
? ? ? - ''
? ? resources:
? ? ? - events
? ? verbs:
? ? ? - create
? ? ? - patch
? - apiGroups:
? ? ? - networking.k8s.io
? ? resources:
? ? ? - ingresses/status
? ? verbs:
? ? ? - update
? - apiGroups:
? ? ? - networking.k8s.io
? ? resources:
? ? ? - ingressclasses
? ? verbs:
? ? ? - get
? ? ? - list
? ? ? - watch
---
# Source: ingress-nginx/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? name: ingress-nginx
roleRef:
? apiGroup: rbac.authorization.k8s.io
? kind: ClusterRole
? name: ingress-nginx
subjects:
? - kind: ServiceAccount
? ? name: ingress-nginx
? ? namespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: controller
? name: ingress-nginx
? namespace: ingress-nginx
rules:
? - apiGroups:
? ? ? - ''
? ? resources:
? ? ? - namespaces
? ? verbs:
? ? ? - get
? - apiGroups:
? ? ? - ''
? ? resources:
? ? ? - configmaps
? ? ? - pods
? ? ? - secrets
? ? ? - endpoints
? ? verbs:
? ? ? - get
? ? ? - list
? ? ? - watch
? - apiGroups:
? ? ? - ''
? ? resources:
? ? ? - services
? ? verbs:
? ? ? - get
? ? ? - list
? ? ? - watch
? - apiGroups:
? ? ? - networking.k8s.io
? ? resources:
? ? ? - ingresses
? ? verbs:
? ? ? - get
? ? ? - list
? ? ? - watch
? - apiGroups:
? ? ? - networking.k8s.io
? ? resources:
? ? ? - ingresses/status
? ? verbs:
? ? ? - update
? - apiGroups:
? ? ? - networking.k8s.io
? ? resources:
? ? ? - ingressclasses
? ? verbs:
? ? ? - get
? ? ? - list
? ? ? - watch
? - apiGroups:
? ? ? - ''
? ? resources:
? ? ? - configmaps
? ? resourceNames:
? ? ? - ingress-controller-leader
? ? verbs:
? ? ? - get
? ? ? - update
? - apiGroups:
? ? ? - ''
? ? resources:
? ? ? - configmaps
? ? verbs:
? ? ? - create
? - apiGroups:
? ? ? - ''
? ? resources:
? ? ? - events
? ? verbs:
? ? ? - create
? ? ? - patch
---
# Source: ingress-nginx/templates/controller-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: controller
? name: ingress-nginx
? namespace: ingress-nginx
roleRef:
? apiGroup: rbac.authorization.k8s.io
? kind: Role
? name: ingress-nginx
subjects:
? - kind: ServiceAccount
? ? name: ingress-nginx
? ? namespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-service-webhook.yaml
apiVersion: v1
kind: Service
metadata:
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: controller
? name: ingress-nginx-controller-admission
? namespace: ingress-nginx
spec:
? type: ClusterIP
? ports:
? ? - name: https-webhook
? ? ? port: 443
? ? ? targetPort: webhook
? ? ? appProtocol: https
? selector:
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
? annotations:
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: controller
? name: ingress-nginx-controller
? namespace: ingress-nginx
spec:
? type: NodePort
? externalTrafficPolicy: Local
? ipFamilyPolicy: SingleStack
? ipFamilies:
? ? - IPv4
? ports:
? ? - name: http
? ? ? port: 80
? ? ? protocol: TCP
? ? ? targetPort: http
? ? ? appProtocol: http
? ? - name: https
? ? ? port: 443
? ? ? protocol: TCP
? ? ? targetPort: https
? ? ? appProtocol: https
? selector:
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-deployment.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: controller
? name: ingress-nginx-controller
? namespace: ingress-nginx
spec:
? selector:
? ? matchLabels:
? ? ? app.kubernetes.io/name: ingress-nginx
? ? ? app.kubernetes.io/instance: ingress-nginx
? ? ? app.kubernetes.io/component: controller
? revisionHistoryLimit: 10
? minReadySeconds: 0
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app.kubernetes.io/name: ingress-nginx
? ? ? ? app.kubernetes.io/instance: ingress-nginx
? ? ? ? app.kubernetes.io/component: controller
? ? spec:
? ? ? hostNetwork: true
? ? ? hostPID: true
? ? ? dnsPolicy: ClusterFirst
? ? ? containers:
? ? ? ? - name: controller
? ? ? ? ? image: docker.io/loging/ingress-nginx-controller:v1.1.1
? ? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? ? lifecycle:
? ? ? ? ? ? preStop:
? ? ? ? ? ? ? exec:
? ? ? ? ? ? ? ? command:
? ? ? ? ? ? ? ? ? - /wait-shutdown
? ? ? ? ? args:
? ? ? ? ? ? - /nginx-ingress-controller
? ? ? ? ? ? - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
? ? ? ? ? ? - --election-id=ingress-controller-leader
? ? ? ? ? ? - --controller-class=k8s.io/ingress-nginx
? ? ? ? ? ? - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
? ? ? ? ? ? - --validating-webhook=:8443
? ? ? ? ? ? - --validating-webhook-certificate=/usr/local/certificates/cert
? ? ? ? ? ? - --validating-webhook-key=/usr/local/certificates/key
? ? ? ? ? securityContext:
? ? ? ? ? ? capabilities:
? ? ? ? ? ? ? drop:
? ? ? ? ? ? ? ? - ALL
? ? ? ? ? ? ? add:
? ? ? ? ? ? ? ? - NET_BIND_SERVICE
? ? ? ? ? ? runAsUser: 101
? ? ? ? ? ? allowPrivilegeEscalation: true
? ? ? ? ? env:
? ? ? ? ? ? - name: POD_NAME
? ? ? ? ? ? ? valueFrom:
? ? ? ? ? ? ? ? fieldRef:
? ? ? ? ? ? ? ? ? fieldPath: metadata.name
? ? ? ? ? ? - name: POD_NAMESPACE
? ? ? ? ? ? ? valueFrom:
? ? ? ? ? ? ? ? fieldRef:
? ? ? ? ? ? ? ? ? fieldPath: metadata.namespace
? ? ? ? ? ? - name: LD_PRELOAD
? ? ? ? ? ? ? value: /usr/local/lib/libmimalloc.so
? ? ? ? ? livenessProbe:
? ? ? ? ? ? failureThreshold: 5
? ? ? ? ? ? httpGet:
? ? ? ? ? ? ? path: /healthz
? ? ? ? ? ? ? port: 10254
? ? ? ? ? ? ? scheme: HTTP
? ? ? ? ? ? initialDelaySeconds: 10
? ? ? ? ? ? periodSeconds: 10
? ? ? ? ? ? successThreshold: 1
? ? ? ? ? ? timeoutSeconds: 1
? ? ? ? ? readinessProbe:
? ? ? ? ? ? failureThreshold: 3
? ? ? ? ? ? httpGet:
? ? ? ? ? ? ? path: /healthz
? ? ? ? ? ? ? port: 10254
? ? ? ? ? ? ? scheme: HTTP
? ? ? ? ? ? initialDelaySeconds: 10
? ? ? ? ? ? periodSeconds: 10
? ? ? ? ? ? successThreshold: 1
? ? ? ? ? ? timeoutSeconds: 1
? ? ? ? ? ports:
? ? ? ? ? ? - name: http
? ? ? ? ? ? ? containerPort: 80
? ? ? ? ? ? ? protocol: TCP
? ? ? ? ? ? - name: https
? ? ? ? ? ? ? containerPort: 443
? ? ? ? ? ? ? protocol: TCP
? ? ? ? ? ? - name: webhook
? ? ? ? ? ? ? containerPort: 8443
? ? ? ? ? ? ? protocol: TCP
? ? ? ? ? volumeMounts:
? ? ? ? ? ? - name: webhook-cert
? ? ? ? ? ? ? mountPath: /usr/local/certificates/
? ? ? ? ? ? ? readOnly: true
? ? ? ? ? resources:
? ? ? ? ? ? requests:
? ? ? ? ? ? ? cpu: 100m
? ? ? ? ? ? ? memory: 90Mi
? ? ? nodeSelector:
? ? ? ? kubernetes.io/os: linux
? ? ? serviceAccountName: ingress-nginx
? ? ? terminationGracePeriodSeconds: 300
? ? ? volumes:
? ? ? ? - name: webhook-cert
? ? ? ? ? secret:
? ? ? ? ? ? secretName: ingress-nginx-admission
---
# Source: ingress-nginx/templates/controller-ingressclass.yaml
# We don't support namespaced ingressClass yet
# So a ClusterRole and a ClusterRoleBinding is required
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: controller
? name: nginx
? namespace: ingress-nginx
spec:
? controller: k8s.io/ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
# before changing this value, check the required kubernetes version
# https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: admission-webhook
? name: ingress-nginx-admission
webhooks:
? - name: validate.nginx.ingress.kubernetes.io
? ? matchPolicy: Equivalent
? ? rules:
? ? ? - apiGroups:
? ? ? ? ? - networking.k8s.io
? ? ? ? apiVersions:
? ? ? ? ? - v1
? ? ? ? operations:
? ? ? ? ? - CREATE
? ? ? ? ? - UPDATE
? ? ? ? resources:
? ? ? ? ? - ingresses
? ? failurePolicy: Fail
? ? sideEffects: None
? ? admissionReviewVersions:
? ? ? - v1
? ? clientConfig:
? ? ? service:
? ? ? ? namespace: ingress-nginx
? ? ? ? name: ingress-nginx-controller-admission
? ? ? ? path: /networking/v1/ingresses
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
? name: ingress-nginx-admission
? namespace: ingress-nginx
? annotations:
? ? helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
? ? helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: admission-webhook
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
? name: ingress-nginx-admission
? annotations:
? ? helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
? ? helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: admission-webhook
rules:
? - apiGroups:
? ? ? - admissionregistration.k8s.io
? ? resources:
? ? ? - validatingwebhookconfigurations
? ? verbs:
? ? ? - get
? ? ? - update
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
? name: ingress-nginx-admission
? annotations:
? ? helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
? ? helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: admission-webhook
roleRef:
? apiGroup: rbac.authorization.k8s.io
? kind: ClusterRole
? name: ingress-nginx-admission
subjects:
? - kind: ServiceAccount
? ? name: ingress-nginx-admission
? ? namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
? name: ingress-nginx-admission
? namespace: ingress-nginx
? annotations:
? ? helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
? ? helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: admission-webhook
rules:
? - apiGroups:
? ? ? - ''
? ? resources:
? ? ? - secrets
? ? verbs:
? ? ? - get
? ? ? - create
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
? name: ingress-nginx-admission
? namespace: ingress-nginx
? annotations:
? ? helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
? ? helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: admission-webhook
roleRef:
? apiGroup: rbac.authorization.k8s.io
? kind: Role
? name: ingress-nginx-admission
subjects:
? - kind: ServiceAccount
? ? name: ingress-nginx-admission
? ? namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
apiVersion: batch/v1
kind: Job
metadata:
? name: ingress-nginx-admission-create
? namespace: ingress-nginx
? annotations:
? ? helm.sh/hook: pre-install,pre-upgrade
? ? helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: admission-webhook
spec:
? template:
? ? metadata:
? ? ? name: ingress-nginx-admission-create
? ? ? labels:
? ? ? ? helm.sh/chart: ingress-nginx-4.0.15
? ? ? ? app.kubernetes.io/name: ingress-nginx
? ? ? ? app.kubernetes.io/instance: ingress-nginx
? ? ? ? app.kubernetes.io/version: 1.1.1
? ? ? ? app.kubernetes.io/managed-by: Helm
? ? ? ? app.kubernetes.io/component: admission-webhook
? ? spec:
? ? ? containers:
? ? ? ? - name: create
? ? ? ? ? image: lianyuxue1020/kube-webhook-certgen:v1.1.1
? ? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? ? args:
? ? ? ? ? ? - create
? ? ? ? ? ? - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
? ? ? ? ? ? - --namespace=$(POD_NAMESPACE)
? ? ? ? ? ? - --secret-name=ingress-nginx-admission
? ? ? ? ? env:
? ? ? ? ? ? - name: POD_NAMESPACE
? ? ? ? ? ? ? valueFrom:
? ? ? ? ? ? ? ? fieldRef:
? ? ? ? ? ? ? ? ? fieldPath: metadata.namespace
? ? ? ? ? securityContext:
? ? ? ? ? ? allowPrivilegeEscalation: false
? ? ? restartPolicy: OnFailure
? ? ? serviceAccountName: ingress-nginx-admission
? ? ? nodeSelector:
? ? ? ? kubernetes.io/os: linux
? ? ? securityContext:
? ? ? ? runAsNonRoot: true
? ? ? ? runAsUser: 2000
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
apiVersion: batch/v1
kind: Job
metadata:
? name: ingress-nginx-admission-patch
? namespace: ingress-nginx
? annotations:
? ? helm.sh/hook: post-install,post-upgrade
? ? helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
? labels:
? ? helm.sh/chart: ingress-nginx-4.0.15
? ? app.kubernetes.io/name: ingress-nginx
? ? app.kubernetes.io/instance: ingress-nginx
? ? app.kubernetes.io/version: 1.1.1
? ? app.kubernetes.io/managed-by: Helm
? ? app.kubernetes.io/component: admission-webhook
spec:
? template:
? ? metadata:
? ? ? name: ingress-nginx-admission-patch
? ? ? labels:
? ? ? ? helm.sh/chart: ingress-nginx-4.0.15
? ? ? ? app.kubernetes.io/name: ingress-nginx
? ? ? ? app.kubernetes.io/instance: ingress-nginx
? ? ? ? app.kubernetes.io/version: 1.1.1
? ? ? ? app.kubernetes.io/managed-by: Helm
? ? ? ? app.kubernetes.io/component: admission-webhook
? ? spec:
? ? ? containers:
? ? ? ? - name: patch
? ? ? ? ? image: lianyuxue1020/kube-webhook-certgen:v1.1.1
? ? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? ? args:
? ? ? ? ? ? - patch
? ? ? ? ? ? - --webhook-name=ingress-nginx-admission
? ? ? ? ? ? - --namespace=$(POD_NAMESPACE)
? ? ? ? ? ? - --patch-mutating=false
? ? ? ? ? ? - --secret-name=ingress-nginx-admission
? ? ? ? ? ? - --patch-failure-policy=Fail
? ? ? ? ? env:
? ? ? ? ? ? - name: POD_NAMESPACE
? ? ? ? ? ? ? valueFrom:
? ? ? ? ? ? ? ? fieldRef:
? ? ? ? ? ? ? ? ? fieldPath: metadata.namespace
? ? ? ? ? securityContext:
? ? ? ? ? ? allowPrivilegeEscalation: false
? ? ? restartPolicy: OnFailure
? ? ? serviceAccountName: ingress-nginx-admission
? ? ? nodeSelector:
? ? ? ? kubernetes.io/os: linux
? ? ? securityContext:
? ? ? ? runAsNonRoot: true
? ? ? ? runAsUser: 2000

kubectl apply -f??deploy.yaml? 他会去下载相应的镜像和容器

这两running就ok了

Jenkins构建

访问应用

查看svc暴露的端口

root@master:/data/xiangmu/xx# cat /var/nfsdata/nginx/index.html? ? ?添加前端测试页面
hello boy !!!

访问后端tomcat已经出现git项目的代码内容

二十二.nginx和tomcat和ingrss yaml详解

#创建命名空间dev

apiVersion: v1
kind: Namespace
metadata:
? name: dev

#创建一个 Kubernetes 的 ConfigMap,用于存储 Nginx 的配置文件。这个配置文件包含了 Nginx 的基本配置,包括 worker_processes、error_log、events、http 等部分
?

apiVersion: v1
kind: ConfigMap
metadata:
? name: nginx-config
? namespace: dev
data: #ConfigMap挂载配置文件
? nginx.conf: |
? ? user ?nginx;
? ? worker_processes ?auto;
? ? error_log ?/var/log/nginx/nginx-error.log notice;
? ? pid ? ? ? ?/var/run/nginx.pid;
? ??
? ??
? ? events {
? ? ? ? worker_connections ?1024;
? ? }
? ??
? ??
? ? http {
? ? ? ? include ? ? ? /etc/nginx/mime.types;
? ? ? ? default_type ?application/octet-stream;
? ? ? ? log_format ?main ?'$remote_addr - $remote_user [$time_local] "$request" '
? ? ? ? ? ? ? ? ? ? ? ? ? '$status $body_bytes_sent "$http_referer" '
? ? ? ? ? ? ? ? ? ? ? ? ? '"$http_user_agent" "$http_x_forwarded_for"';
? ? ? ? access_log ?/var/log/nginx/access.log ?main;
? ? ? ? sendfile ? ? ? ?on;
? ? ? ? keepalive_timeout ?65;
? ? ? ? include /etc/nginx/conf.d/*.conf;
? ? }

#您正在创建一个名为?nginx-pv?的持久卷(Persistent Volume)用于存储 Nginx 的数据,并且指定了其大小为 1GB。这个持久卷将使用 NFS(Network File System)作为存储后端,具有 ReadWriteMany 的访问模式,这意味着多个 Pod 可以同时对其进行读写操作。

apiVersion: v1
kind: PersistentVolume
metadata: ? #创建nginx pv 指定大小1G
? name: nginx-pv
? namespace: dev
spec:
? capacity:
? ? storage: 1Gi
? accessModes:
? ? - ReadWriteMany
? nfs:
? ? server: 192.168.189.132
? ? path: /var/nfsdata/nginx

#创建一个名为 "nginx-pvc" 的 PersistentVolumeClaim(持久卷声明)在 "dev" 命名空间中。该 PVC 请求 1GB 的存储空间,具有 ReadWriteMany 访问模式,并且会尝试与一个名为 "nginx-pv" 的 PersistentVolume 绑定。此外,它还包含一个选择器,用于匹配标签为 "type: nginx" 的 PersistentVolume。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:   #创建pvc
  name: nginx-pvc
  namespace: dev
spec:
  storageClassName: ""
  volumeName: nginx-pv
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      type: nginx

#下面的tomcat的和上面nginx一样

apiVersion: v1
kind: PersistentVolume
metadata:  #创建tomcat pv 指定大小1G
  name: tomcat-pv
  namespace: dev
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.189.132
    path: /var/nfsdata/tomcat

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: tomcat-pvc
  namespace: dev
spec:
  storageClassName: ""
  volumeName: tomcat-pv
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      type: tomcat

#创建一个名为 "nginx-deployment" 的 Deployment(部署)在 "dev" 命名空间中。这个 Deployment 包含了两个副本,使用一个标签选择器来匹配 Pod,并且定义了一个 Pod 模板,其中包含了两个卷和一个容器。

其中,第一个卷是一个 ConfigMap 类型的卷,名为 "nginx-config",用于将配置文件注入到 Nginx 容器中。第二个卷是一个持久卷声明(PersistentVolumeClaim),名为 "nfs-volume",它将与名为 "nginx-pvc" 的 PersistentVolumeClaim 绑定,用于将 NFS 卷挂载到 Nginx 容器中。

Nginx 容器使用的是 "nginx:1.17.1" 镜像,监听 80 端口,并且将 "nginx-config" 卷挂载到 "/etc/nginx/nginx.conf" 路径下,将 "nfs-volume" 卷挂载到 "/usr/share/nginx/html" 路径下,这是 Nginx 默认的静态资源文件目录。

apiVersion: apps/v1
kind: Deployment
metadata:  #nginx配置
  name: nginx-deployment
  namespace: dev
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      volumes:
      - name: nginx-config
        configMap:
          name: nginx-config
      - name: nfs-volume
        persistentVolumeClaim:
          claimName: nginx-pvc  # 这里是NFS的PersistentVolumeClaim的名称
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
        - name: nfs-volume
          mountPath: /usr/share/nginx/html  # NGINX默认的静态资源文件目录

#创建一个名为 "tomcat-deployment" 的 Deployment(部署)在 "dev" 命名空间中。这个 Deployment 包含了两个副本,使用一个标签选择器来匹配 Pod,并且定义了一个 Pod 模板,其中包含了一个卷和一个容器。

在 Pod 模板中,使用了 "imagePullSecrets" 字段来指定镜像拉取的凭据,这里使用了名为 "harborsecret" 的凭据。另外,还定义了亲和性(affinity),通过 "podAntiAffinity" 字段来确保同一台节点上不会调度多个具有相同标签的 Pod。

在卷的部分,定义了一个名为 "web-content" 的持久卷声明(PersistentVolumeClaim),用于将存储卷挂载到 Tomcat 容器中。

Tomcat 容器使用的是 "192.168.189.132/java/tomcat:latest" 镜像,总是拉取最新的镜像,监听 8080 端口,并且将 "web-content" 卷挂载到 "/usr/local/tomcat/webapps/ROOT" 路径下。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-deployment
  namespace: dev
spec:
  replicas: 2
  selector:
    matchLabels:
      app: tomcat-pod
  template:
    metadata:
      labels:
        app: tomcat-pod
    spec:
      imagePullSecrets:
        - name: harborsecret
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - tomcat-pod
            topologyKey: "kubernetes.io/hostname"
      volumes:
      - name: web-content
        persistentVolumeClaim:
          claimName: tomcat-pvc
      containers:
      - name: tomcat
        image: 192.168.189.132/java/tomcat:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: web-content
          mountPath: /usr/local/tomcat/webapps/ROOT

#一个名为 "my-ingress" 的 Ingress 资源,用于将外部流量路由到 Kubernetes 集群中的不同服务。这个 Ingress 资源位于 "dev" 命名空间中,并且指定了一些注解和规则来定义路由行为。

在注解部分,使用了 "nginx.ingress.kubernetes.io/rewrite-target" 注解,将请求重写到 "/$2"。

在规则部分,指定了 Ingress 类别为 "nginx",并且定义了两条路由规则。第一条规则将以 "harbor.snow.com" 为主机的所有请求(/)路由到名为 "nginx-service" 的服务的 80 端口上。第二条规则将以 "harbor.snow.com/tomcat" 开头的请求路由到名为 "tomcat-service" 的服务的 8080 端口上。这个 Ingress 资源定义了基于主机和路径的路由规则,用于将外部流量导向到不同的后端服务

?

apiVersion: networking.k8s.io/v1
#apiVersion: v1
kind: Ingress
metadata:
  name: my-ingress
  namespace: dev
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx      
  rules:
    - host: harbor.snow.com
      http:
        paths:
          - path: /(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: nginx-service
                port:
                  number: 80
          - path: /tomcat(/|$)(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: tomcat-service
                port:
                  number: 8080

#创建两个Kubernetes Service资源,分别是"nginx-service"和"tomcat-service",它们都位于"dev"命名空间中。"nginx-service"是ClusterIP类型的服务,这意味着它只能在Kubernetes集群内部访问。它选择具有标签"app: nginx-pod"的Pod,并暴露端口80,"tomcat-service"也是ClusterIP类型的服务,它选择具有标签"app: tomcat-pod"的Pod,并暴露端口8080

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: None
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: tomcat-service
  namespace: dev
spec:
  selector:
    app: tomcat-pod
  clusterIP: None
  type: ClusterIP
  ports:
  - port: 8080
    targetPort: 8080

文章来源:https://blog.csdn.net/u014741634/article/details/135228268
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。