K8s学习
一、 kubernetes 概述
1 、 kubernetes 基本介绍
kubernetes,简称 K8s,是用 8 代替 8 个字符“ubernete”而成的缩写。是一个开源
的,用于管理云平台中多个主机上的容器化的应用,Kubernetes 的目标是让部署容器化的
应用简单并且高效(powerful),Kubernetes 提供了应用部署,规划,更新,维护的一种
机制。
传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配
置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等
操作,当然也可以通过创建虚拟机的方式来实现某些功能,但是虚拟机非常重,并不利于
可移植性。
新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件
系统 ,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,
由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进
行迁移。
容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间
成一对一关系也使容器有更大优势,使用容器可以在 build 或 release 的阶段,为应用创
建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,
这使得从研发到测试、生产能提供一致环境。类似地,容器比虚拟机轻量、更“透明”,
这更便于监控和管理。
Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、
应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便
对应用请求进行负载均衡。
在 Kubernetes 中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通
过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需
要运维人员去进行复杂的手工配置和处理。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-njDV8NL2-1641264633446)(K8s学习.assets/02-第一部分 概述特性和架构组件.png)]
二、探针机制
1. 探针介绍
探针有两种类型:存活探针和就绪探针。
Kubelet使用liveness probe(存活探针)来确定何时重启容器。当应用程序处于运行状态但无法做进一步操作,liveness探针将捕获到deadlock,重启处于该状态下的容器,使应用程序在存在bug的情况下依然能够继续运行下去。
Kubelet使用readiness probe(就绪探针)来确定容器是否已经就绪可以接受流量。只有当Pod中的容器都处于就绪状态时kubelet才会认定该Pod处于就绪状态。该信号的作用是控制哪些Pod应该作为service的后端。如果Pod处于非就绪状态,那么它们将会被从service的load balancer中移除。
2. 定义 liveness命令
Liveness探针有三种检测方式,分别是exec方式、http方式和tcp方式。
1. 定义一个exec的liveness探针案例
apiVersion: v1
kind: Podmetadata:
labels:
test: liveness
name: liveness-execspec:
containers:
\- name: liveness
args:
\- /bin/sh
\- -c
\- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
image: gcr.io/google_containers/busybox
livenessProbe:
exec:
command:
\- cat
\- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
该配置文件给Pod配置了一个容器。periodSeconds 规定kubelet要每隔5秒执行一次liveness probe。 initialDelaySeconds 告诉kubelet在第一次执行probe之前要的等待5秒钟。探针检测命令是在容器中执行 cat /tmp/healthy 命令。如果命令执行成功,将返回0,kubelet就会认为该容器是活着的并且很健康。如果返回非0值,kubelet就会杀掉这个容器并重启它。
容器启动时,执行命令:
/bin/sh -c “touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600”
在容器生命的最初30秒内有一个 /tmp/healthy 文件,在这30秒内 cat /tmp/healthy命令会返回一个成功的返回码。30秒后, cat /tmp/healthy 将返回失败的返回码。
2. 定义一个HTTP的liveness探针案例
apiVersion: v1kind: Podmetadata:
labels:
test: liveness
name: liveness-httpspec:
containers:
\- name: liveness
args:
\- /server
image: gcr.io/google_containers/liveness
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
\- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
该配置文件只定义了一个容器,livenessProbe 指定kubelete需要每隔3秒执行一次liveness probe。initialDelaySeconds 指定kubelet在该执行第一次探测之前需要等待3秒钟。该探针将向容器中的server的8080端口发送一个HTTP GET请求。如果server的/healthz路径的handler返回一个成功的返回码,kubelet就会认定该容器是活着的并且很健康。如果返回失败的返回码,kubelet将杀掉该容器并重启它。
任何大于200小于400的返回码都会认定是成功的返回码。其他返回码都会被认为是失败的返回码。
3. 定义一个TCP的liveness探针案例
第三种liveness probe使用TCP Socket。 使用此配置,kubelet将尝试在指定端口上打开容器的套接字。 如果可以建立连接,容器被认为是健康的,如果不能就认为是失败的。
TCP检查的配置与HTTP检查非常相似。 此示例同时使用了readiness和liveness probe。 容器启动后5秒钟,kubelet将发送第一个readiness probe。 这将尝试连接到端口8080上的goproxy容器。如果探测成功,则该pod将被标记为就绪。Kubelet将每隔10秒钟执行一次该检查。
除了readiness probe之外,该配置还包括liveness probe。 容器启动15秒后,kubelet将运行第一个liveness probe。 就像readiness probe一样,这将尝试连接到goproxy容器上的8080端口。如果liveness probe失败,容器将重新启动。
使用命名的端口
可以使用命名的ContainerPort作为HTTP或TCP liveness检查:
ports:
\- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
3. 定义readiness探针
应用程序有时暂时无法对外部流量提供服务。 例如,应用程序可能需要在启动期间加载大量数据或配置文件。 在这种情况下,在不杀死应用程序,也不想发送请求的情况下。可以使用readiness probe来检测和减轻这些情况。 Pod中的容器可以报告自己还没有准备,不能处理Kubernetes服务发送过来的流量。
Readiness probe的配置跟liveness probe很像。唯一的不同是使用 readinessProbe而不是livenessProbe,检测方式也是相同,有三种方式。
readinessProbe:
exec:
command:
\- cat
\- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
Readiness probe的HTTP和TCP的探测器配置跟liveness probe一样。
Readiness和livenss probe可以并行用于同一容器。 使用两者可以确保流量无法到达未准备好的容器,并且容器在失败时重新启动。
4. 配置Probe参数
Probe中有很多精确和详细的配置,通过它们你能准确的控制liveness和readiness检查:
· initialDelaySeconds:容器启动后第一次执行探测是需要等待多少秒。
· periodSeconds:执行探测的频率。默认是10秒,最小1秒。
· timeoutSeconds:探测超时时间。默认1秒,最小1秒。
· successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1。对于liveness必须是1。最小值是1。
· failureThreshold:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。
HTTP probe中可以给 httpGet设置其他配置项:
· host:连接的主机名,默认连接到pod的IP。你可能想在http header中设置”Host”而不是使用IP。
· scheme:连接使用的schema,默认HTTP。
· path: 访问的HTTP server的path。
· httpHeaders:自定义请求的header。HTTP运行重复的header。
· port:访问的容器的端口名字或者端口号。端口号必须介于1和65525之间。
对于HTTP探测器,kubelet向指定的路径和端口发送HTTP请求以执行检查。 Kubelet将probe发送到容器的IP地址,除非地址被httpGet中的可选host字段覆盖。
三、K8s容器亲和性
1. Node Affinity
Affinity 翻译成中文是“亲和性”,它对应的是 Anti-Affinity,我们翻译成“互斥”。这两个词比较形象,可以把 pod 选择 node 的过程类比成磁铁的吸引和互斥,不同的是除了简单的正负极之外,pod 和 node 的吸引和互斥是可以灵活配置的。
Affinity的优点:
· 匹配有更多的逻辑组合,不只是字符串的完全相等
· 调度分成软策略(soft)和硬策略(hard),在软策略下,如果没有满足调度条件的节点,pod会忽略这条规则,继续完成调度。
目前主要的node affinity:
(1)requiredDuringSchedulingIgnoredDuringExecution
表示pod必须部署到满足条件的节点上,如果没有满足条件的节点,就不停重试。其中IgnoreDuringExecution表示pod部署之后运行的时候,如果节点标签发生了变化,不再满足pod指定的条件,pod也会继续运行。
(2)requiredDuringSchedulingRequiredDuringExecution
表示pod必须部署到满足条件的节点上,如果没有满足条件的节点,就不停重试。其中RequiredDuringExecution表示pod部署之后运行的时候,如果节点标签发生了变化,不再满足pod指定的条件,则重新选择符合要求的节点。
(3)preferredDuringSchedulingIgnoredDuringExecution
表示优先部署到满足条件的节点上,如果没有满足条件的节点,就忽略这些条件,按照正常逻辑部署。
(4)preferredDuringSchedulingRequiredDuringExecution
表示优先部署到满足条件的节点上,如果没有满足条件的节点,就忽略这些条件,按照正常逻辑部署。其中RequiredDuringExecution表示如果后面节点标签发生了变化,满足了条件,则重新调度到满足条件的节点。
这里的匹配逻辑是label在某个列表中,可选的操作符有:
· In: label的值在某个列表中
· NotIn:label的值不在某个列表中
· Exists:某个label存在
· DoesNotExist:某个label不存在
· Gt:label的值大于某个值(字符串比较)
· Lt:label的值小于某个值(字符串比较)
案例:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
\- labelSelector:
matchExpressions:
\- key: "role"
operator: In
values:
\- coordinator
topologyKey: "kubernetes.io/hostname"
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
\- matchExpressions:
\- key: "kubernetes.io/hostname"
operator: In
values:
\- jfimpala017
\- jfimpala019
四、语法案例
apiVersion: v1
kind: Service
matadata: # 元数据
name: string # service的名称
namespace: string # 命名空间
labels: # 自定义标签属性列表
- name: string
annotations: # 自定义注解属性列表
- name: string
spec: # 详细描述
selector: [] # label selector配置,将选择具有label标签的Pod作为管理
type: string # service的类型,指定service的访问方式,默认为
clusterIP: string # 虚拟服务地址
sessionAffinity: string # 是否支持session
ports: # service需要暴露的端口列表
- name: string # 端口名称
protocol: string # 端口协议,支持TCP和UDP,默认TCP
port: int # 服务监听的端口号
targetPort: int # 需要转发到后端Pod的端口号
nodePort: int # 当type = NodePort时,指定映射到物理机的端口号
status: # 当spce.type=LoadBalancer时,设置外部负载均衡器的地址
loadBalancer: # 外部负载均衡器
ingress: # 外部负载均衡器
ip: string # 外部负载均衡器的Ip地址值
hostname: string # 外部负载均衡器的主机名
externalTrafficPolicy: Local # 与主机ip端口绑定在一起,即该主机的该端口只与该命名空间下的选择这个server的pod通信
---
apiVersion: extensions/v1beta1 #接口版本
kind: Deployment #接口类型
metadata:
name: ptengine-demo #Deployment名称
namespace: ptengine-prd #namespace 名称
labels:
app: ptengine-demo #标签
spec:
replicas: 3
strategy:
rollingUpdate: ##由于replicas为3,则整个升级,pod个数在2-4个之间
maxSurge: 1 #滚动升级时会先启动1个pod
maxUnavailable: 1 #滚动升级时允许的最大Unavailable的pod个数
template:
metadata:
labels:
app: ptengine-demo #模板名称必填
sepc: #定义容器模板,该模板可以包含多个容器
containers:
- name: ptengine-demo #镜像名称
image: reg.pt1.com/ptengine-prd/ptengine-demo:0.0.1-SNAPSHOT #镜像地址
CMD: [ "/bin/sh","-c","cat /etc/config/path/to/special-key" ] #启动CMD
args: #启动参数
- '-storage.local.retention=$(STORAGE_RETENTION)'
- '-web.external-url=$(EXTERNAL_URL)'
imagePullPolicy: IfNotPresent #如果不存在则拉取
livenessProbe: #表示container是否处于live状态。如果LivenessProbe失败,LivenessProbe将会通知kubelet对应的container不健康了。随后kubelet将kill掉container,并根据RestarPolicy进行进一步的操作。默认情况下LivenessProbe在第一次检测之前初始化值为Success,如果container没有提供LivenessProbe,则也认为是Success;
httpGet:
path: /health #如果没有心跳检测接口就为/
port: 8080
scheme: HTTP
initialDelaySeconds: 60 ##启动后延时多久开始运行检测
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe:
readinessProbe:
httpGet:
path: /health #如果没有健康检测接口就为/
port: 8080
scheme: HTTP
initialDelaySeconds: 30 ##启动后延时多久开始运行检测
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
resources: ##CPU内存限制
requests:
cpu: 2
memory: 2048Mi
limits:
cpu: 2
memory: 2048Mi
env: ##通过环境变量的方式,直接传递pod=自定义Linux OS环境变量
- name: LOCAL_KEY #本地Key
value: value
- name: CONFIG_MAP_KEY #local策略可使用configMap的配置Key,
valueFrom:
configMapKeyRef:
name: special-config #configmap中找到name为special-config
key: special.type #找到name为special-config里data下的key
ports:
- name: http
containerPort: 8080 #对service暴露端口
volumeMounts: #挂载volumes中定义的磁盘
- name: log-cache
mount: /tmp/log
- name: sdb #普通用法,该卷跟随容器销毁,挂载一个目录
mountPath: /data/media
- name: nfs-client-root #直接挂载硬盘方法,如挂载下面的nfs目录到/mnt/nfs
mountPath: /mnt/nfs
- name: example-volume-config #高级用法第1种,将ConfigMap的log-script,backup-script分别挂载到/etc/config目录下的一个相对路径path/to/...下,如果存在同名文件,直接覆盖。
mountPath: /etc/config
- name: rbd-pvc #高级用法第2中,挂载PVC(PresistentVolumeClaim)
#使用volume将ConfigMap作为文件或目录直接挂载,其中每一个key-value键值对都会生成一个文件,key为文件名,value为内容,
volumes: # 定义磁盘给上面volumeMounts挂载
- name: log-cache
emptyDir: {}
- name: sdb #挂载宿主机上面的目录
hostPath:
path: /any/path/it/will/be/replaced
- name: example-volume-config # 供ConfigMap文件内容到指定路径使用
configMap:
name: example-volume-config #ConfigMap中名称
items:
- key: log-script #ConfigMap中的Key
path: path/to/log-script #指定目录下的一个相对路径path/to/log-script
- key: backup-script #ConfigMap中的Key
path: path/to/backup-script #指定目录下的一个相对路径path/to/backup-script
- name: nfs-client-root #供挂载NFS存储类型
nfs:
server: 10.42.0.55 #NFS服务器地址
path: /opt/public #showmount -e 看一下路径
- name: rbd-pvc #挂载PVC磁盘
persistentVolumeClaim:
claimName: rbd-pvc1 #挂载已经申请的pvc磁盘
#单个pod的语法,与控制器类型的pod语法相似,可互用
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选,Pod
metadata: #必选,元数据
name: string #必选,Pod名称
namespace: string #必选,Pod所属的命名空间
labels: #自定义标签
- name: string #自定义标签名字
annotations: #自定义注释列表
- name: string
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [Always | Never | IfNotPresent] #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: string #端口号名称
containerPort: int #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: string #端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
- name: string #环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置
cpu: string #Cpu请求,容器启动的初始可用数量
memory: string #内存清楚,容器启动的初始可用数量
livenessProbe: #对Pod内个容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
httpGet: #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0 #容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 0 #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged:false
restartPolicy: [Always | Never | OnFailure]#Pod的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
- name: string
hostNetwork:false #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes: #在该pod上定义共享存储卷列表
- name: string #共享存储卷名称 (volumes类型有很多种)
emptyDir: {} #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string #Pod所在宿主机的目录,将被用于同期中mount的目录
secret: #类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
五、K8s集群部署
1.卸载k8s组件
在卸载K8s组件前,先执行kubeadm reset命令,清空K8s集群设置
kubeadm reset
卸载管理组件
yum erase -y kubelet kubectl kubeadm kubernetes-cni
删除基础组件镜像。基础组件通过Docker镜像部署,因此只需要强制删除对应镜像即可卸载。
docker rmi -f k8s.gcr.io/kube-apiserver:v1.15.1
docker rmi -f k8s.gcr.io/kube-controller-manager:v1.15.1
docker rmi -f k8s.gcr.io/kube-scheduler:v1.15.1
docker rmi -f k8s.gcr.io/kube-proxy:v1.15.1
docker rmi -f k8s.gcr.io/pause:3.1
docker rmi -f k8s.gcr.io/etcd:3.3.10
docker rmi -f k8s.gcr.io/coredns:1.3.1
2.卸载Docker
杀死docker有关的容器:
docker kill $(docker ps -a -q)
删除所有docker容器:
docker rm $(docker ps -a -q)
删除所有docker镜像:
docker rmi $(docker images -q)
停止 docker 服务:
systemctl stop docker
删除docker相关存储目录:
rm -rf /etc/docker
rm -rf /run/docker
rm -rf /var/lib/dockershim
rm -rf /var/lib/docker
如果删除不掉,则先umount:
umount /var/lib/docker/devicemapper
然后再重新执行上面那步“删除docker相关存储目录”。
经过上面一系列准备后,我们终于到了最后环节,开始删除docker。
查看系统已经安装了哪些docker包:
[root@localhost ~]# yum list installed | grep docker
containerd.io.x86_64 1.2.13-3.2.el7 @docker-ce-stable
docker-ce.x86_64 3:19.03.12-3.el7 @docker-ce-stable
docker-ce-cli.x86_64 1:19.03.12-3.el7 @docker-ce-stable
卸载相关包:
[root@localhost ~]# yum remove containerd.io.x86_64 docker-ce.x86_64 docker-ce-cli.x86_64
接着会出现选择提示,直接输入“y”然后回车就可以。
注意,卸载相关包的时候,是要根据上面查询出来的包名对应上去。我是通过“yum list installed | grep docker”命令搜索出我这边安装了以下包:
containerd.io.x86_64
docker-ce.x86_64
docker-ce-cli.x86_64
所以我删除的时候,是直接一次性删除三个,拼接成以下命令:
yum remove containerd.io.x86_64 docker-ce.x86_64 docker-ce-cli.x86_64
到时大家根据自己的实际情况来删除即可。
执行完上述操作后,我们重新执行以下命令,看是否已经成功删除:
yum list installed | grep docker
不再出现相关信息,证明删除成功,再看看docker命令:
[root@localhost ~]# docker version
-bash: /usr/bin/docker: No such file or directory
因此,成功卸载Docker
3.Kubernetes集群升级(kubeadm升级方式)
参考:(128条消息) Kubernetes集群升级(kubeadm升级方式)_???111的博客-CSDN博客
1、升级前的版本确认(相同的大版本号下的小版本升级还是跨版本升级)
例如:从1.12.0升级到1.12.7 或者 从1.12.7升级到1.13.0
2、配置kubernetes安装源(已配置kubernetes源,此处跳过)
Debian/Ubuntu添加源方式:
apt-get update && apt-get install -y apt-transport-https
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y kubelet kubeadm kubectl
CentOS/RHEL/Fedora添加源方式:
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
setenforce 0
yum install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet
注意:如果需要安装特定版本,请参照如下方式
查看版本:
yum --enablerepo=kubernetes list kubelet kubeadm kubectl --showduplicates | sort -r
安装特定版本
yum --enablerepo=kubernetes install kubelet-1.17.0-0 kubeadm-1.17.0-0 kubectl-1.17.0-0
3、验证安装的版本
kubeadm version
4、查看升级后的所需镜像
kubeadm config images list
这里可以提前下载好镜像
kubeadm config images list > images.txt
for i in `cat images.txt`; do docker pull $i; done
5、在主节点上运行如下命令(此命令检查您的群集是否可以升级,并获取可以升级到的版本)
kubeadm upgrade plan
6、选择要升级到的版本,然后运行相应的命令(此处从1.12.7版本升级到1.13.0)
kubeadm upgrade apply v1.13.0
7、将控制节点设置为不可调度
kubectl drain $NODE --ignore-daemonsets
8、重启控制节点的kubelet服务
systemctl daemon-reload
systemctl restart kubelet
9、逐一将除控制节点以外的其他需要升级的节点设置为不可调度
kubectl cordon $NODENAME
kubectl drain $NODENAME
9、在除控制节点的所有节点上逐一执行如下命令升级(注意执行如下命令前,需要先按照步骤2的方法升级程序包)
kubeadm upgrade node config --kubelet-version v1.13.0
10、重新启动升级后节点的kubelet服务
systemctl daemon-reload
systemctl restart kubelet
11、恢复节点为可调度(在控制节点上操作)
kubectl uncordon $NODE
参考:https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-13/
转载于:https://www.cnblogs.com/a120608yby/p/10684296.html
4.、 kubernetes 集群搭建( kubeadm 方式 )
1、 前置知识点
目前生产部署 Kubernetes 集群主要有两种方式:
(1)kubeadm
Kubeadm 是一个 K8s 部署工具,提供 kubeadm init 和 kubeadm join,用于快速部
署 Kubernetes 集群。
官方地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
(2)二进制包
从 github 下载发行版的二进制包,手动部署每个组件,组成 Kubernetes 集群。
Kubeadm 降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可
控,推荐使用二进制包部署 Kubernetes 集群,虽然手动部署麻烦点,期间可以学习很
多工作原理,也利于后期维护。
2 、kubeadm 部署方式介绍
kubeadm 是官方社区推出的一个用于快速部署 kubernetes 集群的工具,这个工具能通
过两条指令完成一个 kubernetes 集群的部署:
第一、创建一个 Master 节点 kubeadm init
第二, 将 Node 节点加入到当前集群中 $ kubeadm join <Master 节点的 IP 和端口 >
3 、安装要求
在开始之前,部署 Kubernetes 集群机器需要满足以下几个条件:
- 一台或多台机器,操作系统 CentOS7.x-86_x64
- 硬件配置:2GB 或更多 RAM,2 个 CPU 或更多 CPU,硬盘 30GB 或更多
- 集群中所有机器之间网络互通
- 可以访问外网,需要拉取镜像
- 禁止 swap 分区
4 、系统初始化
4.1 关闭防火墙:
$ systemctl stop firewalld
$ systemctl disable firewalld
4.2 关闭 selinux:
$ sed -i ‘s/enforcing/disabled/’ /etc/selinux/config # 永久
$ setenforce 0 # 临时
4.3 关闭 swap:
$ swapoff -a # 临时
$ vim /etc/fstab # 永久
4.4 主机名:
$ hostnamectl set-hostname
4.5 在 master 添加 hosts:
$ cat >> /etc/hosts << EOF
192.168.31.61 k8s-master
192.168.31.62 k8s-node1
192.168.31.63 k8s-node2
EOF
4.6 将桥接的 IPv4 流量传递到 iptables 的链:
$ cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sysctl --system # 生效
4.7 时间同步:
$ yum install ntpdate -y
$ ntpdate time.windows.com
5、所有节点安装 Docker/kubeadm/kubelet
Kubernetes 默认 CRI(容器运行时)为 Docker,因此先安装 Docker。
(1)安装 Docker
$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
$ yum -y install docker-ce-18.06.1.ce-3.el7
$ systemctl enable docker && systemctl start docker
$ docker --version
(2)添加阿里云 YUM 软件源
设置仓库地址
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF
(3) 新增kubernetes源
[root@master ~]# cat < /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
[] 中括号中的是repository id,唯一,用来标识不同仓库
name 仓库名称,自定义
baseurl 仓库地址
enable 是否启用该仓库,默认为1表示启用
gpgcheck 是否验证从该仓库获得程序包的合法性,1为验证
repo_gpgcheck 是否验证元数据的合法性 元数据就是程序包列表,1为验证
gpgkey=URL 数字签名的公钥文件所在位置,如果gpgcheck值为1,此处就需要指定gpgkey文件的位置,如果gpgcheck值为0就不需要此项了
更新缓存
[root@master ~]# yum clean all
[root@master ~]# yum -y makecache
(4)安装kubelet
查看版本:
yum --enablerepo=kubernetes list kubelet kubeadm kubectl --showduplicates | sort -r
安装特定版本
yum --enablerepo=kubernetes install kubelet-1.17.1-0 kubeadm-1.17.1-0 kubectl-1.17.1-0
systemctl enable kubelet && systemctl start kubelet
6、部署 Kubernetes Master
每次重启服务时需:kubeadm reset
(1)在 192.168.241.139(Master)执行
kubeadm init
–apiserver-advertise-address=192.168.241.129
–image-repository registry.aliyuncs.com/google_containers
–kubernetes-version v1.17.1
–service-cidr=10.1.0.0/16
–pod-network-cidr=10.244.0.0/16
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iTFlYHTn-1641264633449)(K8s学习.assets/image-20211222154108652.png)]
将当前用户配置为集群管理员(如果不配置,下次连接时会无法使用kubectl)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
部署flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
7、Node节点安装
1.安装kubelet、kubeadm和kubectl
同master节点
2.下载镜像
同master节点
3.加入集群
以下操作master上执行
3.1 查看令牌
[root@master ~]# kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
j5eoyz.zu0x6su7wzh752b3 2019-06-04T17:40:41+08:00 authentication,signing The default bootstrap token generated by ‘kubeadm init’. system:bootstrappers:kubeadm:default-node-token
发现之前初始化时的令牌已过期
3.2 生成新的令牌
[root@master ~]# kubeadm token create
1zl3he.fxgz2pvxa3qkwxln
3.3 生成新的加密串
[root@master ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null |
openssl dgst -sha256 -hex | sed ‘s/^.* //’
3.4 node节点加入集群
在node节点上分别执行如下操作:
kubeadm join --token y2sv1g.tcd4a3oqdkvrdqnz --discovery-token-ca-cert-hash sha256:be750378aab8c32a635aff8ada8a0626a17f9371d62fc8252b7620382f5a742e 192.168.241.129:6443
加入完毕后,我们用命令kubectl get nodes获取所有节点
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 115m v1.15.9
k8s-node1 NotReady <none> 111m v1.15.9
k8s-node2 Ready <none> 111m v1.15.9
验证安装信息
检查系统基础模块健康度
[root@k8s-master ~]# kubectl get componentstatus
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health":"true"}
检查node状态,如果有工作节点NotReady,等几分钟一般就会正常
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready master 115m v1.15.9
k8s-node1 NotReady <none> 111m v1.15.9
k8s-node2 Ready <none> 111m v1.15.9
检查系统pod状态
[root@k8s-master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-94d74667-l8lqt 1/1 Running 0 115m
coredns-94d74667-svgrk 1/1 Running 0 115m
etcd-k8s-master 1/1 Running 0 115m
kube-apiserver-k8s-master 1/1 Running 0 114m
kube-controller-manager-k8s-master 1/1 Running 0 115m
kube-flannel-ds-amd64-64zsm 1/1 Running 0 2m5s
kube-flannel-ds-amd64-csb8h 1/1 Running 0 2m5s
kube-flannel-ds-amd64-nfcsh 1/1 Running 0 2m5s
kube-proxy-b669n 1/1 Running 0 112m
kube-proxy-d84cb 1/1 Running 0 115m
kube-proxy-w7tv7 1/1 Running 0 111m
kube-scheduler-k8s-master 1/1 Running 0 115m
8、测试 kubernetes 集群
在 Kubernetes 集群中创建一个 pod,验证是否正常运行:
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pod,svc
访问地址:http://NodeIP:Port
删除app
kubectl delete pods nginx-86c57db685-45wgx
查看详细
kubectl get pods -o wide
192.168.241.129:31236
9、部署 Dashboard
[root@k8s-master ~]# wget https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
[root@k8s-master ~]# vim kubernetes-dashboard.yaml
修改内容:
109 spec:
110 containers:
111 - name: kubernetes-dashboard
112 image: lizhenliang/kubernetes-dashboard-amd64:v1.10.1 # 修改此行
......
157 spec:
158 type: NodePort # 增加此行
159 ports:
160 - port: 443
161 targetPort: 8443
162 nodePort: 30001 # 增加此行
163 selector:
164 k8s-app: kubernetes-dashboard
[root@k8s-master ~]# kubectl apply -f kubernetes-dashboard.yaml
在火狐浏览器访问(google受信任问题不能访问)地址:192.168.241.139:30001
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ae4y1DnE-1641264633451)(K8s学习.assets/image-20211222210428560.png)]
[root@k8s-master ~]# kubectl create serviceaccount dashboard-admin -n kube-system
serviceaccount/dashboard-admin created
[root@k8s-master ~]# kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin
--serviceaccount=kube-system:dashboard-admin
[root@k8s-master ~]# kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
Name: dashboard-admin-token-d9jh2
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name: dashboard-admin
kubernetes.io/service-account.uid: 4aa1906e-17aa-4880-b848-8b3959483323
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1025 bytes
namespace: 11 bytes
token: eyJhbGciOiJ...(省略如下)...AJdQ
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tZDlqaDIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNGFhMTkwNmUtMTdhYS00ODgwLWI4NDgtOGIzOTU5NDgzMzIzIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.OkF6h7tVQqmNJniCHJhY02G6u6dRg0V8PTiF8xvMuJJUphLyWlWctgmplM4kjKVZo0fZkAthL7WAV5p_AwAuj4LMfo1X5IpxUomp4YZyhqgsBM0A2ksWoKoLDjbizFwOty8TylWlsX1xcJXZjmP9OvNgjjSq5J90N5PnxYIIgwAMP3fawTP7kUXxz5WhJo-ogCijJCFyYBHoqHrgAbk9pusI8DpGTNIZxBMxkwPPwFwzNCOfKhD0c8HjhNeliKsOYLryZObRdmTQXmxsDfxynTKsRxv_EPQb99yW9GXJPQL0OwpYb4b164CFv857ENitvvKEOU6y55P9hFkuQuAJdQ
解决其他浏览器不能访问的问题
[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EEN6phx5-1641264633454)(K8s学习.assets/copycode.gif)]](javascript:void(0)