K8s部署及服务总结

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. 定义一个HTTPliveness探针案例

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. 定义一个TCPliveness探针案例

第三种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)

上一篇:GUI编程---贪吃蛇小游戏开发


下一篇:Scrapy框架的基本使用