【云原生|Kubernetes】Kubernetes核心技术万字大总结

举报
陈橘又青 发表于 2022/09/28 16:05:26 2022/09/28
【摘要】 1. Kubernetes介绍Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署,规划,更新,维护的一种机制。Kubernetes一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着,管理员可以加载一个微型服务,让规划器来找到合适的位置,同时,...

在这里插入图片描述

1. Kubernetes介绍

Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署,规划,更新,维护的一种机制。

Kubernetes一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着,管理员可以加载一个微型服务,让规划器来找到合适的位置,同时,Kubernetes也系统提升工具以及人性化方面,让用户能够方便的部署自己的应用。

2. Kubernetes架构

Kubernetes 搭建需要至少两个节点,一个Master负责管理,一个Slave搭建在工作服务器上负责分配。

kubernetes架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yh6owflO-1661737294552)(Pictures/image-20211210114507638.png)]

从图中可以看到各个组件的基本功能:

  • API Server:作为K8s通讯的核心组件,K8s内部交互以及接收发送指令的组件。
  • controller-manager:作为K8s的核心组件,主要做资源调度,根据集群情况分配资源
  • etcd:一个key-value的数据库,存储存储集群的状态信息
  • scheduler:负责调度每个工作节点
  • cloud-controller-manager:负责调度其他云服务产品
  • kubelet:管理Pods上面的容器。
  • kube-proxy:负责处理其他Slave或客户端的请求。
  • Pod:可以理解为就是运行的容器

3. Kubernetes安装

这里会采用https://kuboard.cn/提供的方式安装K8s,安装单Master节点:

  • 要求使用Centos7.8版本
  • 至少2台 2核4G 的服务器

安装流程

安装流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0vTYh7eL-1661737294552)(Pictures/image-20211210190653687.png)]

准备好服务器后开始安装:

重新设置hostname,不允许为localhost

# 修改 hostname,名字不允许使用下划线、小数点、大写字母,不能叫master
hostnamectl set-hostname your-new-host-name
# 查看修改结果
hostnamectl status
# 设置 hostname 解析
echo "127.0.0.1   $(hostname)" >> /etc/hosts

要求2台服务之间可以相互通讯

首先初始化Master节点

关于初始化时用到的环境变量

  • APISERVER_NAME 不能是 master 的 hostname
  • APISERVER_NAME 必须全为小写字母、数字、小数点,不能包含减号
  • POD_SUBNET 所使用的网段不能与 master节点/worker节点 所在的网段重叠。该字段的取值为一个 CIDR 值,如果您对 CIDR 这个概念还不熟悉,请仍然执行 export POD_SUBNET=10.100.0.0/16 命令,不做修改

设置ip,域名,网段并执行初始化操作

# 只在 master 节点执行
# 替换 x.x.x.x 为 master 节点实际 IP(请使用内网 IP)
# export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
export MASTER_IP=192.168.11.32
# 替换 apiserver.demo 为 您想要的 dnsName
export APISERVER_NAME=apiserver.demo
# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
export POD_SUBNET=10.100.0.1/16
echo "${MASTER_IP}    ${APISERVER_NAME}" >> /etc/hosts
curl -sSL https://kuboard.cn/install-script/v1.19.x/init_master.sh | sh -s 1.19.5

检查Master启动状态

# 只在 master 节点执行

# 执行如下命令,等待 3-10 分钟,直到所有的容器组处于 Running 状态
watch kubectl get pod -n kube-system -o wide

# 查看 master 节点初始化结果
kubectl get nodes -o wide

Ps:如果出现NotReady的情况执行(最新版本的BUG,1.19一般没有)

docker pull quay.io/coreos/flannel:v0.10.0-amd64 
mkdir -p /etc/cni/net.d/
cat <<EOF> /etc/cni/net.d/10-flannel.conf
{"name":"cbr0","type":"flannel","delegate": {"isDefaultGateway": true}}
EOF
mkdir /usr/share/oci-umount/oci-umount.d -p
mkdir /run/flannel/
cat <<EOF> /run/flannel/subnet.env
FLANNEL_NETWORK=172.100.0.0/16
FLANNEL_SUBNET=172.100.1.0/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
EOF
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml

安装网络服务插件

export POD_SUBNET=10.100.0.0/16
kubectl apply -f https://kuboard.cn/install-script/v1.22.x/calico-operator.yaml
wget https://kuboard.cn/install-script/v1.22.x/calico-custom-resources.yaml
sed -i "s#192.168.0.0/16#${POD_SUBNET}#" calico-custom-resources.yaml
kubectl apply -f calico-custom-resources.yaml

初始化worker节点:

获取Join命令参数,在Master节点执行

# 只在 master 节点执行
kubeadm token create --print-join-command
获取命令
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vnjpSL3M-1661737294553)(Pictures/image-20211213183025291.png)]

在worker节点初始化

# 只在 worker 节点执行
# 替换 x.x.x.x 为 master 节点的内网 IP
export MASTER_IP=192.168.11.32
# 替换 apiserver.demo 为初始化 master 节点时所使用的 APISERVER_NAME
export APISERVER_NAME=apiserver.demo
echo "${MASTER_IP}    ${APISERVER_NAME}" >> /etc/hosts

# 替换为 master 节点上 kubeadm token create 命令的输出
kubeadm join apiserver.demo:6443 --token vwfilu.3nhndohc5gn1jv9k     --discovery-token-ca-cert-hash sha256:22ff15cabfe87ab48a7db39b3bbf986fee92ec92eb8efc7fe9b0abe2175ff0c2

检查最终运行效果:

在 master 节点上执行

# 只在 master 节点执行
kubectl get nodes -o wide

Ps:如果出现NotReady的情况执行(最新版本的BUG,1.19一般没有)

docker pull quay.io/coreos/flannel:v0.10.0-amd64 
mkdir -p /etc/cni/net.d/
cat <<EOF> /etc/cni/net.d/10-flannel.conf
{"name":"cbr0","type":"flannel","delegate": {"isDefaultGateway": true}}
EOF
mkdir /usr/share/oci-umount/oci-umount.d -p
mkdir /run/flannel/
cat <<EOF> /run/flannel/subnet.env
FLANNEL_NETWORK=172.100.0.0/16
FLANNEL_SUBNET=172.100.1.0/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
EOF
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml

输出结果如下所示:

[root@k8smaster ~]# kubectl get nodes
搭建成功效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SEhQe0VZ-1661737294553)(Pictures/image-20211210184851810.png)]

安装Kuboard管理K8s集群:

安装Kuboard

kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3.yaml
# 您也可以使用下面的指令,唯一的区别是,该指令使用华为云的镜像仓库替代 docker hub 分发 Kuboard 所需要的镜像
# kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3-swr.yaml

查看启动情况

watch kubectl get pods -n kuboard
查看效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s3zYjtbo-1661737294554)(Pictures/image-20211213184701784.png)]

在浏览器中打开链接 http://your-node-ip-address:30080

首页
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZqBhJU1V-1661737294554)(Pictures/image-20211213184742709.png)]

输入初始用户名和密码,并登录

  • 用户名: admin
  • 密码: Kuboard123
首页效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i4ay09i9-1661737294554)(Pictures/image-20211213184840120.png)]

4. Kubernetes操作

首先我们要了解Kubernetes在运行我们的资源时,关联到了哪些内容:

资源的构建方式:

  • 采用kubectl的命令方式
  • yaml文件方式

4.1 Namespace

命名空间:主要是为了对Kubernetes中运行的资源进行过隔离, 但是网络是互通的,类似Docker的容器,可以将多个资源配置到一个NameSpace中。而NameSpace可以对不同环境进行资源隔离,默认情况下Kubernetes提供了default命名空间,在构建资源时,如果不指定资源,默认采用default资源。

命令方式:

# 查看现有的全部命名空间
kubectl get ns

# 构建命名空间
kubectl create ns 命名空间名称

# 删除现有命名空间, 并且会删除空间下的全部资源
kubectl delete ns 命名空间名称

yaml文件方式:(构建资源时,设置命名空间)

apiVersion: v1
kind: Namespace
metadata:
  name: test

4.2 Pod

Pod:Kubernetes运行的一组容器,Pod是Kubernetes的最小单位,但是对于Docker而然,Pod中会运行多个Docker容器

命令方式:


    # 查看所有运行的pod
    kubectl get pods -A

    # 查看指定Namespace下的Pod
    kubectl get pod [-n 命名空间]  #(默认default)

    # 创建Pod
    kubectl run pod名称 --image=镜像名称

    # 查看Pod详细信息
    kubectl describe pod pod名称

    # 删除pod
    kubectl delete pod pod名称 [-n 命名空间]  #(默认default)

    # 查看pod输出的日志
    kubectl logs -f pod名称

    # 进去pod容器内部
    kubectl exec -it pod名称 -- bash

    # 查看kubernetes给Pod分配的ip信息,并且通过ip和容器的端口,可以直接访问
    kubectl get pod -owide
    

yaml方式(推荐)

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: 运行的pod名称
  name: pod名称
  namespace: 命名空间
spec:
  containers:
  - image: 镜像名称
    name: 容器名称

# 启动Pod:kubectl apply -f yaml文件名称
# 删除Pod:kubectl delete -f yaml文件名称

Pod中运行多个容器

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: 运行的pod名称
  name: pod名称
  namespace: 命名空间
spec:
  containers:
  - image: 镜像名称
    name: 容器名称
  - image: 镜像名称
    name: 容器名称
…………    

4.3 Deployment

部署时,可以通过Deployment管理和编排Pod

Deployment部署实现:

命令方式:

# 基于Deployment启动容器
kubectl create deployment deployment名称 --image=镜像名称
# 用deployment启动的容器会在被删除后自动再次创建,达到故障漂移的效果
# 需要使用deploy的方式删除deploy
# 查看现在的deployment
kubectl get deployment

# 删除deployment
kubectl delete deployment deployment名称

# 基于Deployment启动容器并设置Pod集群数
kubectl create deployment deployment名称 --image=镜像名称 --replicas 集群个数

配置文件方式:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
       image: nginx
       ports:
       - containerPort: 80

正常使用kubectl运行yaml即可。

弹性伸缩功能:

# 基于scale实现弹性伸缩
kubectl scale deploy/Deployment名称 --replicas 集群个数
# 或者修改yaml文件
kubectl edit deploy Deployment名称
图形化页面修改
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-accKe5I1-1660626781502)(Pictures/image-20220104210823057.png)]

灰度发布:

Deploy可以在部署新版本数据时,成功启动一个pod,才会下线一个老版本的Pod

kubectl set image deployment/Deployment名称 容器名=镜像:版本

4.4 Service

可以将多个Pod对外暴露一个Service,让客户端可以通过Service访问到这一组Pod,并且可以实现负载均衡。

ClusterIP方式:

ClusterIP是集群内部Pod之间的访问方式

命令实现效果:

# 通过生成service映射一个Deployment下的所有pod中的某一个端口的容器
kubectl expose deployment Deployment名称 --port=Service端口号 --target-port=Pod内容器端口

之后通过kubectl get service查看Service提供的ip,即可访问:

kubectl get service
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TEMWVi85-1660626781503)(Pictures/image-20220104214659229.png)]

也可以通过Deployment名称.namespace名称.svc作为域名访问:

在服务容器内执行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1oIOLEWD-1660626781504)(Pictures/image-20220104215030265.png)]

NodePort方式:

ClusterIP的方式只能在Pod内部实现访问,但是一般需要对外暴露网关,所以需要NodePort的方式Pod外暴露访问。

命令实现方式:

# 通过生成service映射一个Deployment下的所有pod中的某一个端口的容器
kubectl expose deployment Deployment名称 --port=Service端口号 --target-port=Pod内容器端口 --type=NodePort
查看Service效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UnuLcS8n-1660626781505)(Pictures/image-20220104222750733.png)]

Service也可以通过yaml文件实现:

apiVersion: v1
kind: Service
metadata:
  labels
    app: nginx
  name: nginx
  spec:
    selector:
      app: nginx
    ports:
    - port: 8888
     protocol: TCP
     targetPort: 80

通过apply启动就也可以创建Service。

测试效果-Deployment部署,通过Service暴露:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-deployment
  template:
    metadata:
      labels:
        app: nginx-deployment
    spec:
      containers:
      - name: nginx-deployment
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-service
  name: nginx-service
spec:
  selector:
    app: nginx-deployment
  ports:
  - port: 8888
    protocol: TCP
    targetPort: 80
  type: NodePort

可以查看到暴露的信息:

Service信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uISN7NEJ-1660626781506)(Pictures/image-20220105205334996.png)]

4.5 Ingress

Kubernetes推荐将Ingress作为所有Service的入口,提供统一的入口,避免多个服务之间需要记录大量的IP或者域名,毕竟IP可能改变,服务太多域名记录不方便。

Ingress底层其实就是一个Nginx, 可以在Kuboard上直接点击安装:

Kuboard安装
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-knigd0U0-1660626781507)(Pictures/image-20220105153343642.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TzRKK6F1-1660626781507)(Pictures/image-20220105153416367.png)]

因为副本数默认为1,但是k8s整体集群就2个节点,所以显示下面即为安装成功。

安装成功
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bJX0fXEJ-1660626781508)(Pictures/image-20220105153502619.png)]

可以将Ingress接收到的请求转发到不同的Service中。

推荐使用yaml文件方式

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  ingressClassName: ingress
  rules:
  - host: nginx.mashibing.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 8888
启动时问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RByYpMlD-1660626781509)(Pictures/image-20220105203819715.png)]

Kuboard安装的Ingress有admission的校验配置,需要先删除配置再启动。

找到指定的ingress的校验信息,删除即可:

删除信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ovG8ttZH-1660626781509)(Pictures/image-20220105204434044.png)]
# 查看校验webhook的配置
kubectl get -A ValidatingWebhookConfiguration

# 删除指定的校验
kubectl delete ValidatingWebhookConfiguration ingress-nginx-admission-my-ingress-controller

配置本地hosts文件

配置hosts
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FfmEOz7r-1660626781510)(Pictures/image-20220105204921272.png)]

记下来既可以访问在Service中暴露的Nginx信息:

服通过Ingress访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UcFGrcI0-1660626781511)(Pictures/image-20220105205407393.png)]

5. Jenkins集成Kubernetes

5.1 准备部署的yml文件

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: test
  name: pipeline
  labels:
    app: pipeline
spec:
  replicas: 2
  selector:
    matchLabels:
      app: pipeline
  template:
    metadata:
      labels:
        app: pipeline    
    spec:
      containers:
      - name: pipeline
        image: 192.168.11.102:80/repo/pipeline:v4.0.0
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  namespace: test
  labels:
    app: pipeline
  name: pipeline  
spec:
  selector:
    app: pipeline
  ports:
  - port: 8081
    targetPort: 8080
  type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: test
  name: pipeline
spec:
  ingressClassName: ingress
  rules:
  - host: mashibing.pipeline.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: pipeline
            port:
              number: 8081

5.2 Harbor私服配置

在尝试用kubernetes的yml文件启动pipeline服务时,会出现Kubernetes无法拉取镜像的问题,这里需要在kubernetes所在的Linux中配置Harbor服务信息,并且保证Kubernetes可以拉取Harbor上的镜像。

设置Master和Worker的私服地址信息:

设置Harbor私服地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rUCVaRkc-1661176293454)(Pictures/1642498962716.png)]

在Kuboard上设置私服密文信息:

设置密文并测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c6CtzKz9-1661176293455)(Pictures/1642498994935.png)]

按照复制指令的位置测试认证,效果如下:

测试效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b2Slq7bV-1661176293456)(Pictures/1642499172789.png)]

5.3 测试使用效果

执行kubectl命令,基于yml启动服务,并且基于部署后服务的提示信息以及Ingress的设置,直接访问:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0mfcqFjw-1661176293456)(Pictures/1642499368121.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qTOeBtip-1661176293457)(Pictures/1642499788199.png)]

5.4 Jenkins远程调用

将pipeline.yml配置到Gitlab中:

配置yml文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j4FThVQQ-1661176293457)(Pictures/1642499885324.png)]

配置Jenkins的目标服务器,可以将yml文件传输到K8s的Master上:

设置目标服务器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kaF8b7an-1661176293458)(Pictures/1642499992148.png)]

修改Jenkinsfile,重新设置流水线任务脚本,并测试效果:

传递yml文件脚本
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R6QQXAj3-1661176293459)(Pictures/1642500061153.png)]
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IbYU8K1d-1661176293459)(Pictures/1642500102996.png)]](https://img-blog.csdnimg.cn/ff4e58a338ba47b385bebfd0cfde9de6.png

设置Jenkins无密码登录k8s-master。

将Jenkins中公钥信息复制到k8s-master的~/.ssh/authorized_keysz中,保证远程连接无密码:

远程执行命令无需密码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mSlLF6qQ-1661176293460)(Pictures/1642500239406.png)]

设置执行kubectl的脚本到Jenkinsfile:

设置Jenkinsfile
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qdh1SWHA-1661176293461)(Pictures/1642500378788.png)]

执行查看效果:

执行流水线
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j4xjDzJR-1661176293461)(Pictures/1642500413802.png)]

可以查看到yml文件是由变化的, 这样k8s就会重新加载

查看效果:

效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mUZV4ppZ-1661176293462)(Pictures/1642500474036.png)]

5. 总结

Kubernetes主要能帮助我们完成:

服务发现和负载均衡:Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。

存储编排:Kubernetes 允许你自动挂载你选择的存储系统,比如本地存储,类似Docker的数据卷。

自动部署和回滚:你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态 更改为期望状态。Kubernetes 会自动帮你根据情况部署创建新容器,并删除现有容器给新容器提供资源。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。