Skip to content

Kubernetes 学习记录

需求产生原因:

docker虚拟化之后,在集群环境下,会产生端口混乱问题。 分布式环境下管理多个服务很是麻烦,需要在不同的机器启动, 比如宿主机开启三个tomcat,进行分布式,端口映射就是一个很麻烦的问题。

kubernetes是什么: kubernetes相当于一个docker的管家,他承包了docker的网络配置,磁盘持久化存储,负责了多个docker分布式启动,支持扩缩容,宕机自动重启等一系列操作,所以k8s 又称为容器编排服务框架。当然,在使用的时候这时候就得有一套k8s的操作命令了,通过k8s的命令来操作docker的行为。 当然,想要彻底理解k8s,一系列的概念就必须要学习了

1. 简介

  1. 资源管理器 :

apache mesos (twitter曾经使用过,2019-5后改为Kubernetes)

Docker Swarm :

Kubernetes:是有google公司根据自己的资源管理器borg,使用go语言开发而来。

  1. Kubernetes特性:

    1. 开源

    2. 轻量级

    3. 弹性伸缩(动态不停服务的增减服务硬件)

    4. 负载均衡 : IPVS

    5. 知识图谱:

      介绍说明:前生今世 Kubernetes框架 Kubernetes关键字

      基础概念: 什么是Pod 、 控制器类型、K8S 、网络通讯模式

      Kubernetes: 构建K8S集群

      资源清单:资源、掌握资源清单的语法、编写Pod、掌握Pod的生命周期(重要)

      Pod控制器: 掌握各种控制器的特点以及使用定义方式。

      服务发现: 掌握SVC原理及其构建方式

      存储: 掌握多种存储类型的特点、并且能够在不同环境中选择合适的存储方案(有自己的见解)

      调度器: 掌握调度器原理、能够根据要求吧Pod定义到想要的节点运行

      安全:集群的认证、鉴权、访问控制、原理及其流程

      HELM:类似于linux yum、掌握HEML原理、HELM模板定义、HELM部署一些常用插件

      运维:修改Kubeadm 达到证书可用期限为10年、能够构建高可用的Kubernetes集群

  2. Kubernetes 核心概念s

    1. Pod
      • 最小部署单元
      • 一组容器的集合
      • 共享网络
      • 生命周期是短暂的
    2. controller
      • 确保预期的pod副本数量
      • 无状态应用部署
      • 有状态应用部署
      • 确保所有的node运行同一个pod
      • 一次任务和定时任务
    3. service
      • 定义一组pod的访问规则

k8s架构

img

img

img

历史关系进程说明:

蜜月期:开始市面只有k8s 一个编排容器,也只有一个容器环境 docker,

后来k8s慢慢做大,有了一个容器接口cri,并有k8s提供跟docker的兼容,因此产生dockershim。后来dockersshim独立出去。在后来k8s 1.24后剔除dockersshim。

此时市面上只有k8s一家独大,docker只能自己开发cri-dockerd对其兼容。


img

K8s 集群部署

  1. 搭建k8s 环境平台规划

    a) 单master

    b) 多master

    • 多master ,master 跟node之间多了一层负载均衡
  2. 硬件要求

shell
#集群初始化
kubeadm init \
--control-plane-endpoint="master1.com" \
--kubernetes-version=v1.21.14  \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/16 \
--token-ttl=0 \
--cri-socket unix:///run/cri-dockerd.sock \
--upload-certs


##--token-ttl duration     默认值:24h0m0s
##令牌被自动删除之前的持续时间(例如 1 s,2 m,3 h)。
##如果设置为 '0',则令牌将永不过期

安装dashboard

  1. 安装
shell
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

更改网络类型为NodePort

kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard

type: NodePort

  1. 创建用户

    yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: admin-user
      namespace: kubernetes-dashboard
  2. 创建规则绑定

    yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: admin-user
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
    - kind: ServiceAccount
      name: admin-user
      namespace: kubernetes-dashboard
  3. 获取token

shell
kubectl -n kubernetes-dashboard create token admin-user

上面无法执行使用下面的,github官方命令是上面的,但是我这个k8s版本安装后执行失败。

kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"

2 k8s 基础概念

2.1. 资源创建方式

  • 命令行
  • YAML
    • yaml字段说明查看命令 kubectl explain pod.spec

2.2. namespace

名称空间用来隔离资源

kubectl create ns hello

kubectl delete ns hello

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: hello

2.3. Pod

pod是k8s中最小单位,一个pod中可以运行多个容器。

命令操作

shell
> 创建一个nginxpod
> kubectl run mynginx --image=nginx

> 查看pod
> kubectl get pods # 默认查看default命名空间的pod

> 检查pod
> kubectl describe pod mynginx # mynginx 为 pod的名称通过kubectl get pods 获取

> 删除 pod
> kubectl delete pod mynginx


`查看pod日志`

> kubectl logs mynginx
> 输出:nginx启动日志

> kubectl logs -f mynginx
> 输出:一直输出实时内容,类似tail -f


# 每个pod - k8s 都会分配一个ip
kubectl get pod -o wide
#使用pod的ip+pod里面运行容器的端口
curl 10.244.3.8:80


#进入nginx 更改页面
kubectl exec -it mynginx -- /bin/bash


`注意:`集群中任意的一个机器或应用都可以访问pod的ip

yaml操作

yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: mynginx
  name: mynginx
spec:
  containers:
  - image: nginx
    name: mynginx
shell
# 创建
kubectl apply -f pod.yaml
# 删除
kubectl delete -f pod.yaml

一个pod多个容器

  • 特性;
  • 同一个pod内的容器
  • 共享网络空间,例如nginx的容器访问tomcat,直接访问127.0.0.1:8080
  • 共享存储,
yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: myapp
  name: myapp
spec:
  containers:
  - image: nginx
    name: mynginx
  - image: tomcat
    name: mytomcat

2.4 pod生命周期

pod创建过程

img

pod的终止过程

img

2.4. Deployment

控制Pod,使Pod拥有多副本,自愈,扩容缩能力。

2.4.1 自愈能力

命令行操作

shell
#创建一个nginx通过deployment
kubectl create deployment mynginx --image=nginx
>
  ~ kubectl get pods 
NAME                      READY   STATUS    RESTARTS   AGE
mynginx-ff886775c-78rrl   1/1     Running   0          21m
>

#通过删除pod的命令删除
kubectl delete pod mynginx-ff886775c-78rrl   >这个不会真正的删除,会删掉这个重启另一个,体现了k8s的自愈能力


#查看deployment
kubectl get deployment -owide

#真正删除deployment
  ~ kubectl delete deployment mynginx

2.4.2 多副本

后缀 --replicas=3

shell
kubectl create deployment mynginx --image=nginx --replicas=3

2.4.3 自动扩缩容

命令行操作

//扩容到5个:

kubectl sacle deploy/mynginx --replicas=5

命令行操作yaml配置文件

kubectl edit deploy mynginx

spec:

progressDeadlineSeconds: 600

replicas: 3

revisionHistoryLimit: 10

2.4.4 滚动更新

滚动更新本质是更换镜像,等一个pod启动一个新的,停止一个旧的,从而完成滚动更新。

命令操作行

kubectl set image deploy/mynginx nginx=nginx:1.16.1 --record

注: --record 记录下来变更

2.4.5 版本回退

shell
# 历史记录
kubectl  rollout history deployment/mynginx
=》结果
  ~ kubectl  rollout history deployment/mynginx
deployment.apps/mynginx 
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deploy/mynginx nginx=nginx:1.16.1 --record=true


# 版本回退
kubectl rollout undo deploy/mynginx --to-revision=1

2.4.6 其他工作负载

  • Deployment:无状态应用,比如微服务,提供多副本功能

  • StatefulSet:有状态应用部署,比如redis,提供稳定的存储、网络等功能

  • DaemonSet:守护型应用部署,比如日志收集组件,在每个机器都运行一份

  • Job/CronJob:定时任务部署,比如垃圾清理组件,可以在指定时间运行。


2.5 Service

Service是 pod的服务发现与负载均衡

img

img

Kubernetes service 定义了一种抽象: 一个pods的逻辑分组,一种可以访问他们的策略 --通常称为微服务,这一组pod能够被service访问到,通常是通过Label Selector

service 能够提供负载均衡的能力,但是在使用上有以下限制。

  • 只提供4层负载均衡能力,为没有7层能力,但有时我们可能需要更多的匹配规则来转发请求,这点上4能负载均衡是不支持的。

注意:这里的是默认没有7层,但是后面添加一个ingress来实现

service的类型:

  • ClusterIP:默认类型,自动分配一个仅仅可以Cluster内部可以访问的虚拟ip

  • NodePort:在ClusterIp基础上为Service在每台机器上绑定一个端口,这样就可以通过<NodeIP>:NodePort 来访问该服务

  • LoadBalancer: 在NodePort的基础上,借助cloud provider 创建一个外部负载均衡器,并将请求转发到<NodeIP>:NodePort

  • ExternalName: 把集群外部的服务引入到集群内部来,在集群内部直接使用,没有任何类型代理被创建,这只有Kubernetes 1.7 或更高版本的kube-dns才支持。

2.5.1 Service 端口暴露

ClusterIP(集群内部访问)

命令行操作

kubectl expose deploy mynginx --port=8000 --target-port=80

shell
  ~ kubectl expose deploy mynginx --port=8000 --target-port=80
service/mynginx exposed
  ~ kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP        26h
mynginx      ClusterIP      10.106.208.37   <none>        8000/TCP       30s
nginx        LoadBalancer   10.104.199.33   <pending>     80:31765/TCP   23h
  ~ curl 10.106.208.37:8000
11111
  ~ curl 10.106.208.37:8000
 333333
  ~ curl 10.106.208.37:8000
 22222

此命令相当于

kubectl expose deploy mynginx --port=8000 --target-port=80 --type=ClusterIP

--type=ClusterIP:意思为只在集群内部暴露

还可以使用服务名访问:规则 ,服务名.所在名称空间.svc

curl mynginx.defalut.svc:8000

注意:此种方式只能在pod内部使用,在集群终端使用无效

NodePort(集群外部可以访问)

kubectl expose deploy mynginx --port=8000 --target-port=80 --type=NodePort

shell
  ~ kubectl get svc                                                           
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP      10.96.0.1        <none>        443/TCP          26h
mynginx      NodePort       10.108.149.195   <none>        8000:32250/TCP   2s
nginx        LoadBalancer   10.104.199.33    <pending>     80:31765/TCP     23h
  ~ curl master1.com:32250
333333
  ~ curl master1.com:32250
22222

默认暴露的端口区间:30000-32767


2.6 Ingress

概念:Service的统一网关入口

img

2.6.1 Ingress安装

shell
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/cloud/deploy.yaml

问题: 安装完成后只能在ingress所处的node能通过ip直接访问,无法通过集群访问

产生原因:

markdown
如果你使用自建的 `Kubernetes` 集群([minikube](https://links.jianshu.com/go?to=https%3A%2F%2Fminikube.sigs.k8s.io%2Fdocs%2Fstart%2F)、[kubeadm](https://links.jianshu.com/go?to=https%3A%2F%2Fkubernetes.io%2Fdocs%2Fsetup%2Fproduction-environment%2Ftools%2Fkubeadm%2Finstall-kubeadm%2F) 等)。
在这种情况下,没有集成 `LoadBalancer`(与 AWS、Google Cloud、阿里云等云厂商不同)。使用此默认设置,你只能使用 `NodePort``Ingress Controller`

这时,如果你部署 `LoadBalancer` 则会出现 `External-IP` 一直处于 `pending` 的问题。

解决方案:安装MetalLB

markdown
由于Kubernetes本身并不提供LoadBalaner Ingress Controller, 因此通常使用云平台本身的loadBalancer,如果你是自己在裸机上搭建Kubernetes,需要手动搭建LoadBalancer Ingress Controller

MetalLB Installation

MetalLB安装步骤: 参考网站:https://metallb.universe.tf/installation/

markdown
# Installation

Before starting with installation, make sure you meet all the [requirements](https://metallb.universe.tf/#requirements). In
particular, you should pay attention to [network addon
compatibility](https://metallb.universe.tf/installation/network-addons/).

If you’re trying to run MetalLB on a cloud platform, you should also
look at the [cloud compatibility](https://metallb.universe.tf/installation/clouds/) page and make sure your cloud platform can work with MetalLB
(most cannot).

There are three supported ways to install MetalLB: using plain Kubernetes
manifests, using Kustomize, or using Helm.

## Preparation

If you’re using kube-proxy in IPVS mode, since Kubernetes v1.14.2 you have to enable strict ARP mode.

*Note, you don’t need this if you’re using kube-router as service-proxy because it is enabling strict ARP by default.*

You can achieve this by editing kube-proxy config in current cluster:
bash
kubectl edit configmap -n kube-system kube-proxy

and set:

yaml
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  strictARP: true

Installation by manifest

To install MetalLB, apply the manifest:

bash
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml

If you want to deploy MetalLB using the FRR mode, apply the manifests:

bash
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-frr.yaml

Please do note that these manifests deploy MetalLB from the main development branch. We highly encourage cloud operators to deploy a stable released version of MetalLB on production environments!

2.6.2 ingress测试

img

生成两个deployment实例

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-server
  labels:
    app: hello-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-server
  template:
    metadata:
      labels:
        app: hello-server
    spec:
      containers:
      - name: hello-server
        image: nginx:1.14.2
        ports:
        - containerPort: 9000

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-demo
  labels:
    app: nginx-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-demo
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - name: nginx-demo
        image: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-demo
  labels:
    app: nginx-demo
spec:
  selector:
    app: nginx-demo
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: hello-server
  labels:
    app: hello-server
spec:
  selector:
    app: hello-server
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 9000

配置ingress

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: "hello.master.com"
    http:
      paths:
      - pathType: Prefix
        path: / 
        backend:
          service:
            name: hello-server
            port:
              number: 8000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress-nginx
spec:
  ingressClassName: nginx
  rules:
  - host: "nginx.master.com"
    http:
      paths:
      - pathType: Prefix
        path: / 
        backend:
          service:
            name: nginx-demo
            port:
              number: 8000

最后修改host域名

shell
 ~ curl  hello.master.com:32268/ 
helloworld 1111
 ~ curl  hello.master.com:32268/ 
helloworld 222222
 ~ 
 ~ curl  nginx.master.com:32268/ INT 
nginx demo 222222
 ~ curl  nginx.master.com:32268/ 
nginx demo 222222
 ~ curl  nginx.master.com:32268/ 
nginx demo 222222
 ~ curl  nginx.master.com:32268/ 
nginxdemo 1111
markdown
<注意:注意:>
当参数 path: /  更改匹配规则时,
如改为:path: /admin   
此时访问 http://域名:端口/admin 
通过ingress后到达pod中nginx的请求路径也是带有参数 /admin 的
注意

ingress高级功能:

具体的参见官方文档:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/

1.路径重写

  • 路径重写重写,解决上面提到的问题

    yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
     annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$2
      name: minimal-ingress-nginx
    spec:
      ingressClassName: nginx
      rules:
      - host: "nginx.master.com"
        http:
          paths:
          - pathType: Prefix
            path: /something(/|$)(.*)
            backend:
              service:
                name: nginx-demo
                port:
                  number: 8000
  • 说明

    shell
    In this ingress definition, any characters captured by (.*) will be assigned to the placeholder $2, which is then used as a parameter in the rewrite-target annotation.
    
    For example, the ingress definition above will result in the following rewrites:
    
        rewrite.bar.com/something rewrites to rewrite.bar.com/
        rewrite.bar.com/something/ rewrites to rewrite.bar.com/
        rewrite.bar.com/something/new rewrites to rewrite.bar.com/new

2.流量限制

  • 参见官方文档

2.6.3 网络模型

img


2.7 存储抽象

img

2.7.1 NFS 安装配置

主节点

shell
# 所有节点安装软件
yum install -y nfs-utils

# 主节点配置
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports

mkdir -p /nfs/data
systemctl enable rpcbind --now
systemctl enable nfs-server --now

#配置生效
exportfs -r

从节点:

shell
#检查主节点开放的目录
showmount -e 192.168.2.201

# 建目录
mkdir -p /nfs/data


#挂载
mount -t nfs 192.168.2.201:/nfs/data/ /nfs/data 

#测试
touch /nfs/data/test.txt

2.7.2 deployment 原生方式数据挂载

注意: node节点上必须部署nfs从节点,不然无法使用。

(坑)一开始我只在master部署了,导致失败,查了半天

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-pv-demo
  labels:
    app: nginx-pv-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pv-demo
  template:
    metadata:
      labels:
        app: nginx-pv-demo
    spec:
      containers:
      - name: nginx-pv-demo
        image: nginx
        volumeMounts:
          - name: html
            mountPath: /usr/share/nginx/html
      volumes:
        - name: html
          nfs: 
            server: 192.168.2.201
            path: /nfs/data/nginx-pv

原生的挂载方式存在以下缺点

  • 删除pod后 在磁盘上的内容无法删除,只能手动删除。

  • 对磁盘资源使用无限制

因此解决方案:\

2.7.4 通过pv&pvc挂载

PV&PVC

Pv:持久卷,将应用需要持久化的数据保存到指定位置

PVC: 持久卷申明,

img

说明:pv组建一个静态的pv池,pod创建一个pvc(相当于一个访问令牌),pvc根据大小会指定适合的空间来使用。如果pod销毁时删除pvc,那么磁盘上的相应数据也会被删

  • 创建步骤:
  1. 执行此配置文件进行创建pv池
yaml
     apiVersion: v1
     kind: PersistentVolume
     metadata:
       name: pv01-10m
     spec:
       capacity:
         storage: 10m
       accessModes:
         - ReadWriteMany
       storageClassName: nfs
       nfs:
         path: /nfs/data/01
         server: 192.168.2.201
     ---
     apiVersion: v1
     kind: PersistentVolume
     metadata:
       name: pv02-1g
     spec:
       capacity:
         storage: 1Gi
       accessModes:
         - ReadWriteMany
       storageClassName: nfs
       nfs:
         path: /nfs/data/02
         server: 192.168.2.201
     ---
     apiVersion: v1
     kind: PersistentVolume
     metadata:
       name: pv03-3g
     spec:
       capacity:
         storage: 3Gi
       accessModes:
         - ReadWriteMany
       storageClassName: nfs
       nfs:
         path: /nfs/data/03
         server: 192.168.2.201
  1. 创建pvc

    yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: nginx-pvc
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 1Gi
      storageClassName: nfs
      # 注意:storageClassName和上面创建的pv的storageClassname 名称相同
  2. 创建通过pvc创建deployment

yaml
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: nginx-pvc-demo
   labels:
     app: nginx-pvc-demo
 spec:
   replicas: 2
   selector:
     matchLabels:
       app: nginx-pvc-demo
   template:
     metadata:
       labels:
         app: nginx-pvc-demo
     spec:
       containers:
       - name: nginx-pvc-demo
         image: nginx
         volumeMounts:
           - name: html
             mountPath: /usr/share/nginx/html
       volumes:
         - name: html
           persistentVolumeClaim:
             claimName: nginx-pvc

 ## 注意:只有成功建立pvc后才能够成功建立deployment

2.7.5 configMap抽取配置

抽取应用配置,并可以自动更新

1). 创建redis.conf 配置集

kubectl create cm redis-conf --from-file=redis.conf

查看配置集

kubectl get cm

查看配置集内容

kubectl edit cm redis-conf -oyaml

yaml
apiVersion: v1
data:
  redis.conf: |
    appendonly yes
kind: ConfigMap
metadata:
  name: redis-conf
  namespace: default
2)redis根据configmap中的配置启动

img

3) 启动调用逻辑

img

2.7.6 Secret

Secret对象类型用来保存敏感信息,例如密码 OAuth 令牌和ssh秘钥。将这些信息放在secret中比放在pod更加方便安全。

创建secret命令

shell
kubectl create secret docker-registry  \
NAME 
--docker-username=user 
--docker-password=password 
--docker-email=email 
[--docker-server=string] 
[--from-literal=key1=value1] 
[--dry-run]


#例如
   kubectl create secret docker-registry \
 my-secret \
--docker-server=DOCKER_REGISTRY_SERVER \
--docker-username=DOCKER_USER \
--docker-password=DOCKER_PASSWORD \
--docker-email=DOCKER_EMAIL

使用secret

img

yaml
apiVersion: v1
kind: pod
metadata:
  name: private-nginx
spec:
  containers:
  - name: private-nginx
    image: 仓库镜像路径
  imagePullSecrets:
  - name: my-secret

2.8 污点

helm

是什么

HeLm是一个Kubernetes应用程序包管理工具,它允许你轻松管理和部署Kubernetes)应用程序。HeLm通过使用称为Charts的预定义模板来简化 Kubernetes/应用程序的部署和管理。Chart包含了一组Kubernetes对象定义,可以描述一个应用程序的完整部署和资源需求,包括Deployment、 Service、ConfigMap、Secret等。使用Helm,你可以轻松地安装、升级、卸载和回滚Kubernetes应用程序。 同时,HeLm还提供了一些便捷的功能,如依赖管理、全局变量、条件渲染等,可以帮助你更好地管理应用程序的部署。HeLm有两个主要的组件:HeLm客户端 (helm)和Helm服务器(Tiller).Helm客户端可以在本地运行,而Tiller则运行在Kubernetes:集群中,并负责将Charts转换为Kubernetes对象。

安装

概念

==chart== Chart 代表着 Helm 包。它包含在 Kubernetes 集群内部运行应用程序,工具或服务所需的所有资源定义。你可以把它看作是 Homebrew formula,Apt dpkg,或 Yum RPM 在Kubernetes 中的等价物

==_Repository== Repository(仓库) 是用来存放和共享 charts 的地方。它就像 Perl 的 CPAN 档案库网络 或是 Fedora 的 软件包仓库,只不过它是供 Kubernetes 包所使用的。

==Release== Release 是运行在 Kubernetes 集群中的 chart 的实例。一个 chart 通常可以在同一个集群中安装多次。每一次安装都会创建一个新的 release。以 MySQL chart为例,如果你想在你的集群中运行两个数据库,你可以安装该chart两次。每一个数据库都会拥有它自己的 release 和 release name


3. kubeSphere

3.1 kubeSphere 安装

3.1.1 环境准备

环境准备

主节点:

master1 master2 master3

从节点:

node1 node2 node3

配置:

内存:4G

cpu: 2核心 (i7-12700)

硬盘:20G

3.1.2 版本选择

  1. 软件版本选择: KubeSphere: V3.3.1

  2. kubernetes : v1.21.14 kuberSphere版本要求:

markdown
您的 Kubernetes 版本必须为:v1.19.x、v1.20.x、v1.21.x、* v1.22.x、* v1.23.x 和 * v1.24.x。带星号的版本可能出现边缘节点部分功能不可用的情况。因此,如需使用边缘节点,推荐安装 v1.21.x 及之前的版本
  1. docker版本:
  • 根据k8s的官方文档要求选择版本
  • 要求查看位置:github代码界面》CHANGELOG》

img

3.1.3 安装docker

官方参考文档:Install Docker Engine on CentOS | Docker Documentation

shell
# 卸载旧版本
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

# 添加仓库
sudo yum install -y yum-utils
 sudo yum-config-manager \
 --add-repo \
 https://download.docker.com/linux/centos/docker-ce.repo
 
 #查看版本
   yum list docker-ce --showduplicates | sort -r

   #安装指定版本
    sudo yum install docker-ce-20.10.2-3.el7 docker-ce-cli-20.10.2-3.el7 containerd.io docker-compose-plugin

   #设置开机自启并启动
    sudo systemctl enable docker --now

   #测试
    sudo docker run hello-world

#配置docker cgroup驱动,在/etc/docker/daemon.json 添加
#{

#"exec-opts": ["native.cgroupdriver=systemd"]

#}
cat >> /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
    
    #重启服务
    systemctl restart docker
    #查看是否成功
    docker info | grep Cgroup

注意:

docker 被墙了,所以必须翻墙才可以成功安装,但是在终端配置export 无法访问,必须按照如下配置。

mkdir -p /etc/systemd/system/docker.service.d vim /etc/systemd/system/docker.service.d/proxy.conf

把此内容放到proxy.conf中,docker就可以通过代理访问了。(巨坑,fuck GFW)

shell
[Service]
Environment="HTTP_PROXY=http://192.168.137.1:10809/"
Environment="HTTPS_PROXY=http://192.168.137.1:10809/"
Environment="NO_PROXY=localhost,127.0.0.1,.example.com"

3.1.4 安装kubernetes

1. 前置准备:
  • 关闭swap

    swapoff -a

    把/etc/fstab 中的swap注释掉

  • 配置host

shell
cat >> /etc/hosts <<EOF

192.168.2.201 master1.com

192.168.2.202 master2.com

192.168.2.203 master3.com

192.168.2.204 node1.com

192.168.2.205 node2.com

192.168.2.206 node3.com

EOF
  • 设置hostname
shell
  • 关闭SELinux

    shell
    #查看状态
    getenforce
    #或者
    /usr/sbin/sestatus -v
    
    # 将 SELinux 设置为 permissive 模式(相当于将其禁用)
    sudo setenforce 0
    sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config


* 关闭防火墙

  > 关闭防火墙
  > 
  > systemctl stop firewalld
  > 
  > 禁止开机自启
  > 
  > systemctl disable firewalld

* 转发ipv4 并让iptables看到桥接流量

  ```shell
  cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
  overlay
  br_netfilter
  EOF

  sudo modprobe overlay
  sudo modprobe br_netfilter

  # 设置所需的 sysctl 参数,参数在重新启动后保持不变
  cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
  net.bridge.bridge-nf-call-iptables  = 1
  net.bridge.bridge-nf-call-ip6tables = 1
  net.ipv4.ip_forward                 = 1
  EOF

  # 应用 sysctl 参数而不重新启动
  sudo sysctl --system
  • 安装cir-dockerd (kubernetes 1.24后需要安装,1.24去除了内置dockershim )

    如果版本大于等于1.24需要安装

    https://github.com/Mirantis/cri-dockerd

    从github下载下来相应版本安装即可。

    注意:安装完成后设置开机自启并启动。 systemctl enable --now cri-docker

2. 安装k8s

安装kubeadm

shell
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

sudo yum install -y kubelet-1.21.14 kubeadm-1.21.14 kubectl-1.21.14 --disableexcludes=kubernetes

sudo systemctl enable --now kubelet

初始化 admin init

shell
#集群初始化
kubeadm init \
--apiserver-advertise-address=192.168.2.201 \
--control-plane-endpoint="master1.com" \
--kubernetes-version=v1.21.14  \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/16 \
--upload-certs


##--token-ttl duration     默认值:24h0m0s
##令牌被自动删除之前的持续时间(例如 1 s,2 m,3 h)。
##如果设置为 '0',则令牌将永不过期
--apiserver-advertise-address string

The IP address the API Server will advertise it's listening on. If not set the default network interface will be used.
--upload-certs
Upload control-plane certificates to the kubeadm-certs Secret.

flannel安装卸载

flannel 网络卸载: 由于想换成calico,但是已经安装了flannel,所以进行卸载

shell
#第一步,在master节点删除flannel
kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

#第二步,在node节点清理flannel网络留下的文件
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/
rm -f /etc/cni/net.d/*
3. calico安装
4. NFS安装配置
a) 安装NFS

由于kubesphere需要默认存储类型,需要自己安装,这里使用nfs作为默认存储。

但是nfs需要设置成动态供应,上面有讲述静态供应配置。

主节点

shell
# 所有节点安装软件
yum install -y nfs-utils

# 主节点配置
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports

mkdir -p /nfs/data
systemctl enable rpcbind --now
systemctl enable nfs-server --now

#配置生效
exportfs -r

从节点:

注意:这里的从节点指的是所有node节点

shell
#检查主节点开放的目录
showmount -e 192.168.2.201

# 建目录
mkdir -p /nfs/data


#挂载
mount -t nfs 192.168.2.201:/nfs/data/ /nfs/data 

#测试
touch /nfs/data/test.txt
b) 配置nfs默认存储

注意:这里所有的master节点都要更改

markdown
注意:k8s 1.21版本中创建pvc时nfs-provisioner会报错

    E0903 08:00:24.858523 1 controller.go:1004] provision “default/test-claim” class “managed-nfs-storage”: unexpected error getting claim reference: selfLink was empty, can’t make reference

解决方法:
修改 /etc/kubernetes/manifests/kube-apiserver.yaml文件
增加 - --feature-gates=RemoveSelfLink=false

spec:
  containers:
  - command:
    - kube-apiserver
    - --feature-gates=RemoveSelfLink=false   # 增加这行
    - --advertise-address=172.24.0.5
    - --allow-privileged=true
    - --authorization-mode=Node,RBAC
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    ... 省略剩余部分 ...
————————————————
版权声明:本文为CSDN博主「简单生活FF」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/gxf1027/article/details/120063398

架构图

img

由于kubesphere需要默认存储,这里把nfs配置成动态供应作为默认存储。

NFS作为默认存储的动态供应方式

创建nfs-provisioner.yaml文件,

nfs-client-provisioner 是一个 Kubernetes 的简易 NFS 的外部 provisioner,本身不提供 NFS,需要现有的 NFS 服务器提供存储。 注意:地址和目录要改成实际的NFS服务对应配置

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default  #与RBAC文件中的namespace保持一致
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: nfs-storage  #provisioner名称,请确保该名称与 nfs-StorageClass.yaml文件中的provisioner名称保持一致
            - name: NFS_SERVER
              value: 192.168.2.201    #NFS Server IP地址
            - name: NFS_PATH  
              value: /nfs/data    #NFS挂载卷
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.2.201  #NFS Server IP地址
            path: /nfs/data     #NFS 挂载卷

创建nfs-StorageClass.yaml文件

StorageClass是对存储资源的抽象定义,对用户设置的PVC申请屏蔽后端存储的细节,减轻管理员手工管理PV的工作,由系统自动完成PV的创建和绑定,实现动态资源供给。 StorageClass的定义主要包括名称、后端存储的提供者(provisioner)和后端存储对应的参数。对于后端NFS存储来说,配置相对简单,只需要指定provisioner即可。

yaml
# nfs-StorageClass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"			#作为default中默认的sc
provisioner: nfs-storage #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
reclaimPolicy: Delete # 默认为delete
parameters:
  archiveOnDelete: "true" # false表示pv被删除时,在nfs下面对应的文件夹也会被删除,true正相反

创建rbac.yaml

以下开始部署nfs-provisioner 注意:本次测试都部署在default namespace下,如果需要部署到其他的ns,需要修改yaml文件中namespace。 (1)创建ServiceAccount、ClusterRole、ClusterRoleBinding等,为nfs-client-provisioner授权

yaml
# rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
    # replace with namespace where provisioner is deployed
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

`

创建测试

#创建pve
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nfs-pvc
  annotations:
    volume.beta.kubernetes.io/storage-class: "nfs-storage"
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
---      
# 创建deployment

最后更新于: