美文网首页k8s
DevOps之Kubernetes编排工具

DevOps之Kubernetes编排工具

作者: 羋学僧 | 来源:发表于2022-07-12 06:25 被阅读0次

    1、 Kubernetes介绍

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

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

    Kubernetes主要能帮助我们完成:

    • 服务发现和负载均衡

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

    • 存储编排

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

    • 自动部署和回滚

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

    • 自动完成装箱计算

      Kubernetes 允许你设置每个容器的资源,比如CPU和内存。

    • 自我修复

      Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的容器,并运行状况检查的容器。

    • 秘钥与配置管理

      Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。


    2、 Kubernetes架构

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

    kubernetes架构

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

    • 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.9版本
    • 至少2台 2核4G 的服务器

    安装流程

    安装流程

    准备好服务器后开始安装

    • 重新设置hostname,不允许为localhost

      # 修改 hostname,名字不允许使用下划线、小数点、大写字母,不能叫master
      hostnamectl set-hostname k8smaster
      # 查看修改结果
      hostnamectl status
      # 设置 hostname 解析
      echo "127.0.0.1   $(hostname)" >> /etc/hosts
      
    • 要求2台服务之间可以相互通讯

    • 安装软件

      # 阿里云 docker hub 镜像
      export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com
      curl -sSL https://kuboard.cn/install-script/v1.19.x/install_kubelet.sh | sh -s 1.19.5
      

    首先初始化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.117.113
      # 替换 apiserver.demo 为 您想要的 dnsName
      export APISERVER_NAME=mhg.com
      # 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
      
      获取命令
    • 在worker节点初始化

      # 只在 worker 节点执行
      # 替换 x.x.x.x 为 master 节点的内网 IP
      export MASTER_IP=192.168.117.113
      # 替换 apiserver.demo 为初始化 master 节点时所使用的 APISERVER_NAME
      export APISERVER_NAME=mhg.com
      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
      
      搭建成功效果

    安装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
      
      查看效果
    • 在浏览器中打开链接 http://your-node-ip-address:30080

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

      • 用户名: admin
      • 密码: Kuboard123
      首页效果

    4、 Kubernetes操作

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

    • 资源的构建方式:

      • 采用kubectl的命令方式
      • yaml文件方式
    4.1、 Namespace
    • 命名空间:主要是为了对Kubernetes中运行的资源进行过隔离, 但是网络是互通的,类似Docker的容器,可以将多个资源配置到一个NameSpace中。而NameSpace可以对不同环境进行资源隔离,默认情况下Kubernetes提供了default命名空间,在构建资源时,如果不指定资源,默认采用default资源。
      命令方式:
      # 查看现有的全部命名空间
      kubectl get ns
    
      # 构建命名空间
      kubectl create ns 命名空间名称
    kubectl create ns mhg
    
      # 删除现有命名空间, 并且会删除空间下的全部资源
      kubectl delete ns 命名空间名称
    kubectl delete ns mhg
    

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

    vim namespace-test.yml
    
    apiVersion: v1
    kind: Namespace
    metadata:
      name: test
    
    kubectl apply -f namespace-test.yml
    
    4.2、 Pod
    • Pod:Kubernetes运行的一组容器,Pod是Kubernetes的最小单位,但是对于Docker而然,Pod中会运行多个Docker容器

      • 命令方式:
        # 查看所有运行的pod
        kubectl get pods -A
    
        # 查看指定Namespace下的Pod
        kubectl get pod [-n 命名空间]  #(默认default)
    kubectl get pod -n test
    
        # 创建Pod
        kubectl run pod名称 --image=镜像名称
    kubectl run nginx --image=nginx:latest
    kubectl run nginx --image=daocloud.io/library/nginx:1.9.1 -n test
    


        # 查看Pod详细信息
        kubectl describe pod pod名称
    kubectl describe pod nginx -n test
    

        # 删除pod
        kubectl delete pod pod名称 [-n 命名空间]  #(默认default)
    kubectl delete pod nginx
    
        # 查看pod输出的日志
        kubectl logs -f pod名称
    kubectl logs -f nginx -n test
    
        # 进去pod容器内部
        kubectl exec -it pod名称 -- bash
    kubectl exec -it nginx -n test -- bash
    
        # 查看kubernetes给Pod分配的ip信息,并且通过ip和容器的端口,可以直接访问
        kubectl get pod -owide
    kubectl get pod -owide -n test
    
    • 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: 容器名称
      …………    
      

      启动后可以查看到

      Kuboard效果
    4.3、 Deployment

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

    Deployment部署实现

    • 命令方式
      # 基于Deployment启动容器
      kubectl create deployment deployment名称 --image=镜像名称
    
    kubectl create deployment deploy-nginx --image=daocloud.io/library/nginx:1.9.1 -n test
    
      # 用deployment启动的容器会在被删除后自动再次创建,达到故障漂移的效果
      # 需要使用deploy的方式删除deploy
    

    image.png
      # 查看现在的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: daocloud.io/library/nginx:1.9.1
            ports:
            - containerPort: 80
    

    正常使用kubectl运行yaml即可

    弹性伸缩功能

    # 基于scale实现弹性伸缩
    kubectl scale deploy/Deployment名称 --replicas 集群个数
    # 或者修改yaml文件
    kubectl edit deploy Deployment名称
    
    图形化页面修改

    灰度发布

    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 expose deployment deploy-nginx --port=8888 --target-port=80 -n test
    

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

    kubectl get service -n test
    
    kubectl get service


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

    在服务容器内执行
    NodePort方式

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

    • 命令实现方式

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

    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:
      namespace: test
      name: nginx-deployment
      labels:
        app: nginx-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: daocloud.io/library/nginx:1.9.1
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      namespace: test
      name: nginx-deployment
      labels:
        app: nginx-deployment
    spec:
      selector:
        app: nginx
      ports:
      - port: 8888
        protocol: TCP
        targetPort: 80
      type: NodePort
    

    可以查看到暴露的信息

    Service信息

    4.5、 Ingress

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

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

    Kuboard安装

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

    安装成功

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

    推荐使用yaml文件方式

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: test
      name: nginx-deployment
      labels:
        app: nginx-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: daocloud.io/library/nginx:1.9.1
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      namespace: test
      name: nginx-deployment
      labels:
        app: nginx-deployment
    spec:
      selector:
        app: nginx
      ports:
      - port: 8888
        protocol: TCP
        targetPort: 80
      type: NodePort
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      namespace: test
      name: nginx-ingress
    spec:
      ingressClassName: ingress
      rules:
      - host: mhg.nginx.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-service
                port:
                  number: 8888
    
    启动时问题

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

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

    删除信息
    # 查看校验webhook的配置
    kubectl get -A ValidatingWebhookConfiguration
    
    # 删除指定的校验
    kubectl delete ValidatingWebhookConfiguration ingress-nginx-admission-my-ingress-controller
    

    配置本地hosts文件

    配置hosts

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

    服通过Ingress访问

    相关文章

      网友评论

        本文标题:DevOps之Kubernetes编排工具

        本文链接:https://www.haomeiwen.com/subject/tukibrtx.html