1 准备服务器
这里准备了三台ubuntu虚拟机,每台一核cpu和2G内存,配置好root账户,并安装好了docker,后续的所有 *** 作都是使用root账户。虚拟机具体信息如下表:
2 安装docker(所有节点)
一般情况使用下面的方法安装即可
指定版本安装(比如版本是17091 ce-0 ubuntu)
$ apt-get install -y docker-ce=17091 ce-0 ubuntu
遇到问题可以参考: 官方教程
3 系统设置(所有节点)
通过kubeadmin安装K8S集群可以做到快速部署,但是如果需要调整K8S各个组件及服务的安全配置,高可用模式,最好通过二进制模式进行K8S的安装
生产环境K8S Master节点最好在3个节点以上,且配置不低于4核16g
生产环境:确保Master高可用,启用安全访问机制
PS:
服务器节点只是起名字,与是否为k8s-master或k8s-node无关,可根据需要增加或删减测试用例的数量,如多台master主机只部署k8s-master组件。多台node主机只部署k8s-node组件
master1 192168100100
node1 192168100101
node2 192168100102
注:本节中创建的证书为部署流程全过程证书,测试用例为openssl生成证书,cfssl生成证书需要参考cfssl生成k8s证书,并在对应配置文件的相关证书位置替换对应证书
在配置文件中需要在[alt_names]设置Master服务的全部域名和IP地址,包括:
参数解析
配置文件详解:
分发配置文件
配置文件详解:
配置详解
分发配置文件
分发配置文件
在三个kube-apiserver的前段部署HAProxy和keepalived,使用VIP(虚拟IP地址)192168100200作为Master的唯一入口地址,供客户端访问
将HAProxy和keepalived均部署为至少有两个实例的高可用架构,以避免单点故障。
接下来在主机master(192168100100)和主机node1(192168100101)中部署
HAProxy负责将客户端请求转发到后端的3个kube-apiserver实例上,keepalived负责维护VIP的高可用
准备 HAProxy 的配置文件 haproxycfg
参数说明:
分发配置文件
在master(192168100100)和node1(192168100101)上使用docker部署HAProxy,并将配置文件挂载到容器的/usr/local/etc/haproxy下
访问192168100100:8888/stats,192168100101:8888/stats
keepalived用于维护VIP地址的高可用,同样在master和node1中部署
主节点配置文件
子节点配置文件
参数解析
主节点和子节点配置异同
健康检查脚本
keeplived需要持续监控HAProxy的运行状态,在某个节点运行不正常时转移到另外的节点上去
监控运行状态需要创建健康检查脚本,定期运行监控
脚本内容如下:
分发脚本
在master(192168100100)和node1(192168100101)上使用docker部署keeplived,并将配置文件挂载到容器的/container/service/keepalived/assets下,将脚本挂载到容器的/usr/bin下
检查ens33网卡是否存在keeplived VIP地址
检测keeplived是否进行转发
注:master集群已经配置完毕,后续需要在node中需要部署docker,kubelet,kube-proxy,且在加入k8s集群后,还需要部署CNI网络插件、DNS插件等
之前已经在master,node1,node2中部署了docker,接下来需要部署其他服务组件,本节部署kubelet组件
参数说明
参数说明
参数说明
当前显示所有node为NOT READY,需要部署完网络插件才可使用
为方便使用kubectl
kubelet 是在每个 Node 节点上运行的主要 “节点代理”。它可以使用以下之一向 apiserver 注册: 主机名(hostname);覆盖主机名的参数;某云驱动的特定逻辑。
kubelet 是基于 PodSpec 来工作的。每个 PodSpec 是一个描述 Pod 的 YAML 或 JSON 对象。 kubelet 接受通过各种机制(主要是通过 apiserver)提供的一组 PodSpec,并确保这些 PodSpec 中描述的容器处于运行状态且运行状况良好。 kubelet 不管理不是由 Kubernetes 创建的容器。
在hdss01-221hostcom和hdss01-222hostcom:主机上 *** 作:
签发kubelet证书:
在运维主机hdss01-200hostcom上:
创建生成证书签名请求(csr)的json配置文件:
hosts:要把使用和可能使用的ip地址都写上。( 一定要先规划好 )
~]# cd /opt/certs/
certs]# vi kubelet-csrjson
{
"CN": "k8s-kubelet",
"hosts": [
"127001",
"10411210",
"10411221",
"10411222",
"10411223",
"10411224",
"10411225",
"10411226",
"10411227",
"10411228"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "henan",
"L": "zhengzhou",
"O": "jx",
"OU": "xxzx"
}
]
}
certs]# cfssl gencert -ca=capem -ca-key=ca-keypem -config=ca-configjson -profile=server kubelet-csrjson |cfssl-json -bare kubelet
把证书复制到运算节点hdss01-221hostcom和hdss01-222hostcom上:
cd /opt/kubernetes/server/bin/cert
scp hdss01-200:/opt/certs/kubeletpem
scp hdss01-200:/opt/certs/kubelet-keypem
创建配置kubeletkubeconfig:
只做一次,最后生成的 kubeletkubeconfig 拷贝至其他节点
conf]# cd /opt/kubernetes/server/bin/conf
set-cluster:
kubectl config set-cluster myk8s
--certificate-authority=/opt/kubernetes/server/bin/cert/capem
--embed-certs=true
--server=>
适用版本: Kubernetes v122 [stable]
一个完整描述的目标并不是一个完整的对象,仅包括能体现用户意图的字段和值。 该目标(intent)可以用来创建一个新对象, 也可以通过服务器来实现与现有对象的合并。
系统支持多个应用者(appliers)在同一个对象上开展协作。
“字段管理(field management)”机制追踪对象字段的变化。 当一个字段值改变时,其所有权从当前管理器(manager)转移到施加变更的管理器。 当尝试将新配置应用到一个对象时,如果字段有不同的值,且由其他管理器管理, 将会引发冲突。 冲突引发警告信号:此 *** 作可能抹掉其他协作者的修改。 冲突可以被刻意忽略,这种情况下,值将会被改写,所有权也会发生转移。
当你从配置文件中删除一个字段,然后应用这个配置文件, 这将触发服务端应用检查此字段是否还被其他字段管理器拥有。 如果没有,那就从活动对象中删除该字段;如果有,那就重置为默认值。 该规则同样适用于 list 或 map 项目。
服务器端应用既是原有 kubectl apply 的替代品, 也是控制器发布自身变化的一个简化机制。
如果你启用了服务器端应用,控制平面就会跟踪被所有新创建对象管理的字段。
用户管理字段这件事,在服务器端应用的场景中,意味着用户依赖并期望字段的值不要改变。 最后一次对字段值做出断言的用户将被记录到当前字段管理器。 这可以通过发送 POST、 PUT、 或非应用(non-apply)方式的 PATCH 等命令来修改字段值的方式实现, 或通过把字段放在配置文件中,然后发送到服务器端应用的服务端点的方式实现。 当使用服务器端应用,尝试着去改变一个被其他人管理的字段, 会导致请求被拒绝(在没有设置强制执行时,参见冲突)。
如果两个或以上的应用者均把同一个字段设置为相同值,他们将共享此字段的所有权。 后续任何改变共享字段值的尝试,不管由那个应用者发起,都会导致冲突。 共享字段的所有者可以放弃字段的所有权,这只需从配置文件中删除该字段即可。
字段管理的信息存储在 managedFields 字段中,该字段是对象的 metadata 中的一部分。
服务器端应用创建对象的简单示例如下:
上述对象在 metadatamanagedFields 中包含了唯一的管理器。 管理器由管理实体自身的基本信息组成,比如 *** 作类型、API 版本、以及它管理的字段。
Note: 该字段由 API 服务器管理,用户不应该改动它。
不过,执行 Update *** 作修改 metadatamanagedFields 也是可实现的。 强烈不鼓励这么做,但当发生如下情况时, 比如 managedFields 进入不一致的状态(显然不应该发生这种情况), 这么做也是一个合理的尝试。
managedFields 的格式在 API 文档中描述。
管理器识别出正在修改对象的工作流程(在冲突时尤其有用), 管理器可以通过修改请求的参数 fieldManager 指定。 虽然 kubectl 默认发往 kubectl 服务端点,但它则请求到应用的服务端点(apply endpoint)。 对于其他的更新,它默认的是从用户代理计算得来。
此特性涉及两类 *** 作,分别是 Apply (内容类型为 application/apply-patch+yaml 的 PATCH 请求) 和 Update (所有修改对象的其他 *** 作)。 这两类 *** 作都会更新字段 managedFields,但行为表现有一点不同。
Note:
不管你提交的是 JSON 数据还是 YAML 数据, 都要使用 application/apply-patch+yaml 作为 Content-Type 的值。
所有的 JSON 文档 都是合法的 YAML。
例如,在冲突发生的时候,只有 apply *** 作失败,而 update 则不会。 此外,apply *** 作必须通过提供一个 fieldManager 查询参数来标识自身, 而此查询参数对于 update *** 作则是可选的。 最后,当使用 apply 命令时,你不能在应用中的对象中持有 managedFields。
一个包含多个管理器的对象,示例如下:
在这个例子中, 第二个 *** 作被管理器 kube-controller-manager 以 Update 的方式运行。 此 update 更改 data 字段的值, 并使得字段管理器被改为 kube-controller-manager。
如果把 update *** 作改为 Apply,那就会因为所有权冲突的原因,导致 *** 作失败。
由服务器端应用实现的合并策略,提供了一个总体更稳定的对象生命周期。 服务器端应用试图依据负责管理它们的主体来合并字段,而不是根据值来否决。 这么做是为了多个主体可以更新同一个对象,且不会引起意外的相互干扰。
当用户发送一个“完整描述的目标”对象到服务器端应用的服务端点, 服务器会将它和活动对象做一次合并,如果两者中有重复定义的值,那就以配置文件的为准。 如果配置文件中的项目集合不是此用户上一次 *** 作项目的超集, 所有缺少的、没有其他应用者管理的项目会被删除。 关于合并时用来做决策的对象规格的更多信息,参见 sigsk8sio/structured-merge-diff
Kubernetes 116 和 117 中添加了一些标记, 允许 API 开发人员描述由 list、map、和 structs 支持的合并策略。 这些标记可应用到相应类型的对象,在 Go 文件或在 CRD 的 OpenAPI 的模式中定义:
若未指定 listType,API 服务器将 patchMergeStrategy=merge 标记解释为 listType=map 并且视对应的 patchMergeKey 标记为 listMapKey 取值。
atomic 列表类型是递归的。
这些标记都是用源代码注释的方式给出的,不必作为字段标签(tag)再重复。
在极少的情况下,CRD 或者内置类型的作者可能希望更改其资源中的某个字段的 拓扑配置,同时又不提升版本号。 通过升级集群或者更新 CRD 来更改类型的拓扑信息与更新现有对象的结果不同。 变更的类型有两种:一种是将字段从 map/set/granular 更改为 atomic, 另一种是做逆向改变。
当 listType、mapType 或 structType 从 map/set/granular 改为 atomic 时,现有对象的整个列表、映射或结构的属主都会变为这些类型的 元素之一的属主。这意味着,对这些对象的进一步变更会引发冲突。
当一个列表、映射或结构从 atomic 改为 map/set/granular 之一 时,API 服务器无法推导这些字段的新的属主。因此,当对象的这些字段 再次被更新时不会引发冲突。出于这一原因,不建议将某类型从 atomic 改为 map/set/granular。
以下面的自定义资源为例:
在 specdata 从 atomic 改为 granular 之前,manager-one 是 specdata 字段及其所包含字段(key1 和 key2)的属主。 当对应的 CRD 被更改,使得 specdata 变为 granular 拓扑时, manager-one 继续拥有顶层字段 specdata(这意味着其他管理者想 删除名为 data 的映射而不引起冲突是不可能的),但不再拥有 key1 和 key2。因此,其他管理者可以在不引起冲突的情况下更改 或删除这些字段。
默认情况下,服务器端应用把自定义资源看做非结构化数据。 所有的键值(keys)就像 struct 的字段一样被处理, 所有的 list 被认为是原子性的。
如果自定义资源定义(Custom Resource Definition,CRD)定义了一个 模式, 它包含类似以前“合并策略”章节中定义过的注解, 这些注解将在合并此类型的对象时使用。
控制器的开发人员可以把服务器端应用作为简化控制器的更新逻辑的方式。 读-改-写 和/或 patch 的主要区别如下所示:
强烈推荐:设置控制器在冲突时强制执行,这是因为冲突发生时,它们没有其他解决方案或措施。
除了通过冲突解决方案提供的并发控制, 服务器端应用提供了一些协作方式来将字段所有权从用户转移到控制器。
最好通过例子来说明这一点。 让我们来看看,在使用 Horizo ntalPodAutoscaler 资源和与之配套的控制器, 且开启了 Deployment 的自动水平扩展功能之后, 怎么安全的将 replicas 字段的所有权从用户转移到控制器。
假设用户定义了 Deployment,且 replicas 字段已经设置为期望的值:
application/ssa/nginx-deploymentyaml
并且,用户使用服务器端应用,像这样创建 Deployment:
然后,为 Deployment 启用 HPA,例如:
现在,用户希望从他们的配置中删除 replicas,所以他们总是和 HPA 控制器冲突。 然而,这里存在一个竟态: 在 HPA 需要调整 replicas 之前会有一个时间窗口, 如果在 HPA 写入字段成为所有者之前,用户删除了replicas, 那 API 服务器就会把 replicas 的值设为 1, 也就是默认值。 这不是用户希望发生的事情,即使是暂时的。
这里有两个解决方案:
首先,用户新定义一个只包含 replicas 字段的配置文件:
application/ssa/nginx-deployment-replicas-onlyyaml
用户使用名为 handover-to-hpa 的字段管理器,应用此配置文件。
在此时间点,用户可以从配置文件中删除 replicas 。
application/ssa/nginx-deployment-no-replicasyaml
注意,只要 HPA 控制器为 replicas 设置了一个新值, 该临时字段管理器将不再拥有任何字段,会被自动删除。 这里不需要执行清理工作。
通过在配置文件中把一个字段设置为相同的值,用户可以在他们之间转移字段的所有权, 从而共享了字段的所有权。 当用户共享了字段的所有权,任何一个用户可以从他的配置文件中删除该字段, 并应用该变更,从而放弃所有权,并实现了所有权向其他用户的转移。
由服务器端应用实现的冲突检测和解决方案的一个结果就是, 应用者总是可以在本地状态中得到最新的字段值。 如果得不到最新值,下次执行应用 *** 作时就会发生冲突。 解决冲突三个选项的任意一个都会保证:此应用过的配置文件是服务器上对象字段的最新子集。
这和客户端应用(Client Side Apply) 不同,如果有其他用户覆盖了此值, 过期的值被留在了应用者本地的配置文件中。 除非用户更新了特定字段,此字段才会准确, 应用者没有途径去了解下一次应用 *** 作是否会覆盖其他用户的修改。
另一个区别是使用客户端应用的应用者不能改变他们正在使用的 API 版本,但服务器端应用支持这个场景。
客户端应用方式时,用户使用 kubectl apply 管理资源, 可以通过使用下面标记切换为使用服务器端应用。
默认情况下,对象的字段管理从客户端应用方式迁移到 kubectl 触发的服务器端应用时,不会发生冲突。
Caution:
保持注解 last-applied-configuration 是最新的。 从注解能推断出字段是由客户端应用管理的。 任何没有被客户端应用管理的字段将引发冲突。
举例说明,比如你在客户端应用之后, 使用 kubectl scale 去更新 replicas 字段, 可是该字段并没有被客户端应用所拥有, 在执行 kubectl apply --server-side 时就会产生冲突。
此 *** 作以 kubectl 作为字段管理器来应用到服务器端应用。 作为例外,可以指定一个不同的、非默认字段管理器停止的这种行为,如下面的例子所示。 对于 kubectl 触发的服务器端应用,默认的字段管理器是 kubectl。
如果你用 kubectl apply --server-side 管理一个资源, 可以直接用 kubectl apply 命令将其降级为客户端应用。
降级之所以可行,这是因为 kubectl server-side apply 会保存最新的 last-applied-configuration 注解。
此 *** 作以 kubectl 作为字段管理器应用到服务器端应用。 作为例外,可以指定一个不同的、非默认字段管理器停止这种行为,如下面的例子所示。 对于 kubectl 触发的服务器端应用,默认的字段管理器是 kubectl。
启用了服务器端应用特性之后, PATCH 服务端点接受额外的内容类型 application/apply-patch+yaml。 服务器端应用的用户就可以把 YAMl 格式的 部分定义对象(partially specified objects)发送到此端点。 当一个配置文件被应用时,它应该包含所有体现你意图的字段。
可以从对象中剥离所有 managedField, 实现方法是通过使用 MergePatch、 StrategicMergePatch、 JSONPatch、 Update、以及所有的非应用方式的 *** 作来覆盖它。 这可以通过用空条目覆盖 managedFields 字段的方式实现。以下是两个示例:
这一 *** 作将用只包含一个空条目的列表覆写 managedFields, 来实现从对象中整个的去除 managedFields。 注意,只把 managedFields 设置为空列表并不会重置字段。 这么做是有目的的,所以 managedFields 将永远不会被与该字段无关的客户删除。
在重置 *** 作结合 managedFields 以外其他字段更改的场景中, 将导致 managedFields 首先被重置,其他改变被押后处理。 其结果是,应用者取得了同一个请求中所有字段的所有权。
Caution: 对于不接受资源对象类型的子资源(sub-resources), 服务器端应用不能正确地跟踪其所有权。 如果你对这样的子资源使用服务器端应用,变更的字段将不会被跟踪。
参考链接:
>
升级内核:>
grep -E '(vmx|svm)' /proc/cpuinfo
yum install qemu virt kvm -y
Question:
Solution:已安装的跳过
yum install qemu virt kvm -y --skip-broken
systemctl start libvirtd
systemctl enable libvirtd
virsh list
yum install -y bridge-utils
#配置桥接模式
cd /etc/sysconfig/network-scripts
cp ifcfg-em2 ifcfg-br0
[root@localhost network-scripts]# vim ifcfg-em2
TYPE=Ethernet
BRIDGE=br0
NAME=em2
UUID=74c8085f-4c0d-4743-b0a0-70e51e3eb877
DEVICE=em2
ONBOOT=yes
#注意IPADDR 要改为自己的
[root@localhost network-scripts]# vim ifcfg-br0
TYPE=Bridge
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=br0
DEVICE=br0
ONBOOT=yes
IPADDR=17216103
PREFIX=24
GATEWAY=1721610254
DNS1=114114114114
systemctl restart network
#验证
brctl show
cd /home/kvm
#创建master虚拟机的存储盘 104
qemu-img create -f qcow2 -o cluster_size=2M k8s-master01qcow2 200G
virt-install --virt-type kvm --os-type=linux --os-variant rhel7 --name k8s-master01qcow2 --memory 8192 --vcpus 4 --disk /home/kvm/k8s-master01qcow2,format=qcow2 --cdrom /home/kvm/CentOS-7-x86_64-DVD-2009iso --network bridge=br0 --graphics vnc,listen=0000 --noautoconsole
#创建worker虚拟机的存储盘 105
qemu-img create -f qcow2 -o cluster_size=2M k8s-worker01qcow2 200G
virt-install --virt-type kvm --os-type=linux --os-variant rhel7 --name k8s-worker01qcow2 --memory 8192 --vcpus 4 --disk /home/kvm/k8s-worker01qcow2,format=qcow2 --cdrom /home/kvm/CentOS-7-x86_64-DVD-2009iso --network bridge=br0 --graphics vnc,listen=0000 --noautoconsole
#创建worker虚拟机的存储盘 103
qemu-img create -f qcow2 -o cluster_size=2M k8s-worker02qcow2 200G
virt-install --virt-type kvm --os-type=linux --os-variant rhel7 --name k8s-worker02qcow2 --memory 32768 --vcpus 32 --disk /home/kvm/k8s-worker02qcow2,format=qcow2 --cdrom /home/kvm/CentOS-7-x86_64-DVD-2009iso --network bridge=br0 --graphics vnc,listen=0000 --noautoconsole
netstat -ntlp | grep 5900
virsh list --all
virsh shutdown k8s-master01qcow2
virsh start k8s-master01qcow2
ssh 172161050 root@starQuest2022
Question:系统启动卡住
Solution:
virsh destroy k8s-master01qcow2
virsh undefine k8s-master01qcow2
Question:更改桥接模式失败引发的问题
Solution:
vi /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=eth0
UUID=c510f2f9-9820-45e8-9c70-65674bd35258
DEVICE=eth0
ONBOOT=yes
IPADDR=172161050
PREFIX=24
GATEWAY=1721610254
DNS1=114114114114
systemctl restart network
Question:
Solution:
vi /root/ssh/known_hosts 删除有问题IP对应行
#设置hostname
hostnamectl set-hostname k8s-master01
hostnamectl set-hostname k8s-worker01
hostnamectl set-hostname k8s-worker02
yum update
yum install wget
yum install vim
rpm --import >
上帝借由各种途径使人变得孤独,好让我们可以走向自己。 ——赫尔曼·黑塞《德米安》
CI即为 持续集成(Continue Integration,简称CI) ,用通俗的话讲,就是 持续的整合版本库代码编译后制作应用镜像 。建立有效的持续集成环境可以减少开发过程中一些不必要的问题、 提高代码质量、快速迭代 等,
Jenkins :基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。
Bamboo : 是一个企业级商用软件,可以部署在大规模生产环境中。
CD即持续交付Continuous Delivery和持续部署Continuous Deployment,用通俗的话说,即可以持续的部署到生产环境给客户使用,这里分为两个阶段,持续交付我理解为满足上线条件的过程,但是没有上线,持续部署,即为上线应用的过程
关于 CD环境 ,我们使用以前搭建好的 K8s集群 ,K8s集群可以实现应用的 健康 检测,动态扩容,滚动更新 等优点,关于K8s集群的搭建,小伙伴可以看看我的其他文章
拉取镜像,启动并设置开机自启
配置docker加速
GitLab 不多介绍。一个基于Git的版本控制平台,,提供了Git仓库管理、代码审查、问题跟踪、活动反馈和wiki,当然同时也提供了
切记:这里的端口要设置成80,要不push项目会提示没有报错,如果宿主机端口被占用,需要把这个端口腾出来
external_url '>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)