美文网首页云原生
七 Kubernetes服务发布入门

七 Kubernetes服务发布入门

作者: 負笈在线 | 来源:发表于2022-05-13 17:03 被阅读0次

    (一) Label& Selector

    Label:对k8s中各种资源进行分类、分组,添加一个具有特别属性的标签
    Selector:通过一个过滤的语法进行查找到对应标签的资源
    Label是k8s中一个比较重要的概念。一个Label的一个key=value的键值对,可以附加到各种资源上。

    Label的匹配规则
    name=nginx:这类是直接匹配
    name!=nginx:匹配标签中没有name=nginx的资源
    name in (A,B):匹配所有具有name=A和name=B标签的资源
    name not in (A):匹配所有不具有标签A的资源


    通过上图可以看到:frontend通过service服务匹配到backend服务器,当service的标签是app=nginx时那么会匹配到backend的两组服务器,但是当service中筛选加上Role=backend-app时,Selector只会筛选到backend服务器组中包含这两种标签的服务器然后进行匹配。

    1.添加Label

    通过下面这条命令可以看到Pod的标签:通过–show-labels参数;最后一列LABELS是Pod的标签

    [root@k8s-master01 ~]# kubectl get pod --show-labels
    NAME READY STATUS RESTARTS AGE LABELS
    busybox 1/1 Running 28 (16h ago) 9d <none>
    hpa-nginx-bd88bdd8f-h8vx7 1/1 Running 0 18h app=hpa-nginx,pod-template-hash=bd88bdd8f
    

    那么我们就可以尝试着用kubectl给Pod添加标签:从上列代码中我们是可以看到busybox是没有标签,通过下面这条命令在查看发现已经有标签app=busybox了。

    [root@k8s-master01 ~]# kubectl label pod busybox app=busybox
    pod/busybox labeled
    [root@k8s-master01 ~]# kubectl get pod --show-labels
    NAME                   READY STATUS RESTARTS AGE LABELS
    busybox 1/1 Running 28 (16h ago) 9d app=busybox
    hpa-nginx-bd88bdd8f-h8vx7 1/1 Running 0 18h app=hpa-nginx,pod-template-hash=bd88bdd8f
    

    如果一个集群中Pod非常多的时候,我们就可以通过用标签筛选的方式找到想要的Pod;-A参数是查看所有的Pod,但是加上-l app=busybox后只会找到符合这个条件的Pod。

    [root@k8s-master01 ~]# kubectl get pod -A -l app=busybox
    NAMESPACE NAME READY STATUS RESTARTS AGE
    default busybox 1/1 Running 28 (16h ago) 9d
    

    2.删除标签

    [root@k8s-master01 ~]# kubectl label pod busybox app-
    pod/busybox unlabeled
    [root@k8s-master01 ~]# kubectl get pod --show-labels
    NAME READY STATUS RESTARTS AGE LABELS
    busybox 1/1 Running 28 (16h ago) 9d <none>
    hpa-nginx-bd88bdd8f-h8vx7 1/1 Running 0 18h app=hpa-nginx,pod-template-hash=bd88bdd8f
    

    3.修改标签

    [root@k8s-master01 ~]# kubectl get pod --show-labels
    NAME             READY STATUS RESTARTS AGE LABELS
    busybox 1/1 Running 28 (16h ago) 9d app=busybox
    hpa-nginx-bd88bdd8f-h8vx7 1/1 Running 0 18h app=hpa-nginx,pod-template-hash=bd88bdd8f
    [root@k8s-master01 ~]# kubectl label pod busybox app=busybox22222 --overwrite
    pod/busybox labeled
    

    可以看出标签已经是修改后的了。

    [root@k8s-master01 ~]# kubectl get pod --show-labels
    NAME READY STATUS RESTARTS AGE LABELS
    busybox       1/1 Running 28 (16h ago) 9d app=busybox22222
    hpa-nginx-bd88bdd8f-h8vx7 1/1 Running 0 18h app=hpa-nginx,pod-template-hash=bd88bdd8f
    

    第 I 条 Selector使用

    Labels是很简单的一个东西,我们看看Selector是怎么用的.过滤出多个条件的pod又该怎么做呢?

    [root@k8s-master01 ~]# kubectl get pod -A --show-labels
    NAMESPACE NAME READY STATUS RESTARTS AGE LABELS
    default busybox 1/1 Running 29 (3m19s ago) 9d app=busybox22222
    default hpa-nginx-bd88bdd8f-h8vx7 1/1 Running 0 18h app=hpa-nginx,pod-template-hash=bd88bdd8f
    kube-system calico-kube-controllers-5dffd5886b-4blh6 1/1 Running 2 (2d1h ago) 9d k8s-app=calico-kube-controllers,pod-template-hash=5dffd5886b
    kube-system calico-node-fvbdq 1/1 Running 2 (2d1h ago) 9d controller-revision-hash=79878cdc56,k8s-app=calico-node,pod-template-generation=1
    kube-system calico-node-g8nqd 1/1 Running 0 9d controller-revision-hash=79878cdc56,k8s-app=calico-node,pod-template-generation=1
    kube-system  calico-node-mdps8 1/1 Running 0 9d controller-revision-hash=79878cdc56,k8s-app=calico-node,pod-template-generation=1
    kube-system calico-node-nf4nt 1/1 Running 1 (4d1h ago) 9d controller-revision-hash=79878cdc56,k8s-app=calico-node,pod-template-generation=1
    kube-system calico-node-sq2ml 1/1 Running 1 (2d1h ago) 9d controller-revision-hash=79878cdc56,k8s-app=calico-node,pod-template-generation=1
    kube-system calico-typha-8445487f56-mg6p8 1/1 Running 0 9d k8s-app=calico-typha,pod-template-hash=8445487f56
    kube-system calico-typha-8445487f56-pxbpj           1/1 Running 1 (2d1h ago) 9d k8s-app=calico-typha,pod-template-hash=8445487f56
    kube-system calico-typha-8445487f56-tnssl 1/1 Running 0 9d k8s-app=calico-typha,pod-template-hash=8445487f56
    kube-system coredns-5db5696c7-67h79 1/1 Running 1 (2d1h ago) 9d k8s-app=kube-dns,pod-template-hash=5db5696c7
    kube-system metrics-server-6bf7dcd649-5fhrw 1/1 Running 2 (4d1h ago) 9d k8s-app=metrics-server,pod-template-hash=6bf7dcd649
    kubernetes-dashboard dashboard-metrics-scraper-7fcdff5f4c-9kk86 1/1 Running 1 (2d1h ago) 9d k8s-app=dashboard-metrics-scraper,pod-template-hash=7fcdff5f4c
    kubernetes-dashboard   kubernetes-dashboard-85f59f8ff7-js9j2 1/1 Running 12 (2d1h ago) 9d k8s-app=kubernetes-dashboard,pod-template-hash=85f59f8ff7
    

    以上就是我们的所有Pod了,我想要找到标签中包含kubernetes-dashboard和kube-dns的容器:

    [root@k8s-master01 ~]# kubectl get pod -A -l 'k8s-app in (kubernetes-dashboard,kube-dns)'
    NAMESPACE NAME READY STATUS RESTARTS AGE
    kube-system coredns-5db5696c7-67h79 1/1 Running 1 (2d1h ago) 9d
    kubernetes-dashboard kubernetes-dashboard-85f59f8ff7-js9j2 1/1 Running 12 (2d1h ago) 9d
    

    找到了这两个Pod,说明这两个Pod中包含这两个标签,可以在上面的所有容器列表里看看这两个Pod是否含有这两个标签。

    还有一种情况是比如我有一批Pod的标签是这样:



    我想查看其中不包含ABB=X的所有Pod,可以这样写:

    # kubectl get po -l ABB!=X,APC=A
    

    这样的话只会找到Pod02和Pod03。

    总结:这个功能不难但是比较重要,也比较常用,一定要知道。

    (二) Service(服务发现与负载均衡机制)

    1.什么是Service?

    Service是逻辑上的一组Pod,一种可以访问Pod的策略,而且其他Pod可以通过Service访问到这个Service代理的Pod,可以把它理解为传统架构中的反向代理。
    相对于Pod而言,Service有一个固定的名称,不会发生改变,并且提供了负载均衡的功能。
    通过Service的定义,可以对客户端应用屏蔽后端Pod实例数量及Pod IP地址的变化,通过负载均衡策略实现请求到后端Pod实例的转发,为客户端应用提供一个稳定的服务访问入口地址。
    Service实现的是微服务架构中的几个核心功能:全自动的服务注册、服务发现、服务负载均衡等。

    2.创建一个Service实例

    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: nginx-svc
      name: nginx-svc
    spec:
      ports:
      - name: http #service端口名称
        port: 80 #service自己的端口
        protocol: TCP #支持TCP UDP SCTP等
        targetPort: 80 #后端应用接口
      - name: https
        port: 443
        protocol: TCP
        targetPort: 443
      selector:
        app: nginx  #这个就是匹配规则,代理标签中有nginx的后端服务器
      sessionAffinity: None
      type: ClusterIP
    

    执行上面的yaml文件,创建一个service

    [root@k8s-master01 ~]# kubectl create -f nginx-svc.yaml
    service/nginx-svc created
    [root@k8s-master01 ~]# kubectl get svc
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9d
    nginx-svc ClusterIP 10.110.150.87 <none> 80/TCP,443/TCP 15s
    

    我们通过访问svc地址就能访问到后端的nginx

    [root@k8s-master01 ~]# curl 10.110.150.87
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    

    在同一个namespace中,其他Pod访问svc只需要curl http://nginx-svc就可以.
    跨namespace的话,需要在svc名称后加.namespace名称就可以了,使用需谨慎,没必要不推荐
    不建议通过IP地址访问,因为IP不是固定的,删除或重建后IP会随机生成。
    注意,以上内容只能在集群内部访问

    3.创建代理外部应用的Service实例

    如果集群外部想访问svc的话,则创建代理外部应用的Service实例
    使用Service代理k8s外部应用的场景
    A:希望在生产中使用某个固定的名称而非IP地址进行访问外部的中间件服务
    B:希望Service指向另一个namespace中或其他集群中的服务
    C:某项目正在迁移至k8s集群,但是一部分服务仍然在集群外部,此时可以使用service代理外部的服务

    下面我们定义一个外部应用的service

    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: nginx-svc-w
      name: nginx-svc-w
    spec:
      ports:
      - name: http 
        port: 80 
        protocol: TCP 
        targetPort: 80 
    #  - name: https
    #    port: 443
    #    protocol: TCP
    #    targetPort: 443
    #  selector:
    #    app: nginx 
      sessionAffinity: None
      type: ClusterIP
    

    区别就是少了这两个参数:

     selector:
     app: nginx
    

    创建成功后查看,可以发现虽然创建成功了但是没有ENDPOINTS

    [root@k8s-master01 ~]# kubectl get svc
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9d
    nginx-svc ClusterIP 10.110.150.87 <none> 80/TCP,443/TCP 31m
    nginx-svc-w ClusterIP 10.110.144.61 <none> 80/TCP   58s
    [root@k8s-master01 ~]# kubectl get ep
    NAME ENDPOINTS AGE
    kubernetes 192.168.10.2:6443,192.168.10.3:6443,192.168.10.4:6443 9d
    nginx-svc 172.17.125.10:443,172.18.195.22:443,172.17.125.10:80 + 1 more... 31m
    

    接下来我们需要手动创建一个自定义的ENDPOINTS
    借用存在的ep生成一个新的ep文件

    [root@k8s-master01 ~]# kubectl get ep nginx-svc -o yaml > nginx-ep-w.yaml
    apiVersion: v1
    kind: Endpoints
    metadata:
      labels:
        app: nginx-svc-w
      name: nginx-svc-w
      namespace: default
    subsets:
    - addresses:
      - ip: 110.242.68.3 # 代理的外部服务的地址
      ports:
      - name: http
        port: 80
        protocol: TCP
    

    可以看到已经有外部的代理了

    [root@k8s-master01 ~]# kubectl create -f nginx-ep-w.yaml
    endpoints/nginx-svc-w created
    [root@k8s-master01 ~]# kubectl get ep
    NAME ENDPOINTS AGE
    kubernetes 192.168.10.2:6443,192.168.10.3:6443,192.168.10.4:6443 9d
    nginx-svc 172.17.125.10:443,172.18.195.22:443,172.17.125.10:80 + 1 more... 47m
    nginx-svc-w 110.242.68.3:80 11s
    

    接下来试试能不能访问成功
    直接访问的话是通的,返回值200

    [root@k8s-master01 ~]# curl baidu.com -I
    HTTP/1.1 200 OK
    Date: Mon, 14 Feb 2022 01:43:18 GMT
    Server: Apache
    Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
    ETag: "51-47cf7e6ee8400"
    Accept-Ranges: bytes
    Content-Length: 81
    Cache-Control: max-age=86400
    Expires: Tue, 15 Feb 2022 01:43:18 GMT
    Connection: Keep-Alive
    Content-Type: text/html
    

    通过访问service的IP可以看到也是通的,返回值200

    [root@k8s-master01 ~]# curl 10.110.144.61 -I
    HTTP/1.1 200 OK
    Date: Mon, 14 Feb 2022 01:44:20 GMT
    Server: Apache
    Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
    ETag: "51-47cf7e6ee8400"
    Accept-Ranges: bytes
    Content-Length: 81
    Cache-Control: max-age=86400
    Expires: Tue, 15 Feb 2022 01:44:20 GMT
    Connection: Keep-Alive
    Content-Type: text/html
    

    如果业务变更ep地址变了怎么办?只需要在ep中将代理的地址更换即可。
    比如我们更换一个taobao的地址测试:

    # 取出taobao的IP
    [root@k8s-master01 ~]# ping taobao.com
    PING taobao.com (140.205.94.189) 56(84) bytes of data.
    64 bytes from 140.205.94.189 (140.205.94.189): icmp_seq=1 ttl=128 time=27.4 ms
    64 bytes from 140.205.94.189 (140.205.94.189): icmp_seq=2 ttl=128 time=27.4 ms
    # 修改ep的yaml文件:nginx-ep-w.yaml
    apiVersion: v1
    kind: Endpoints
    metadata:
     labels:
     app: nginx-svc-w
     name: nginx-svc-w
     namespace: default
    subsets:
    - addresses:
     - ip: 140.205.94.189 # taobao
     ports:
     - name: http
     port: 80
     protocol: TCP
    

    重新加载

    [root@k8s-master01 ~]# kubectl replace -f nginx-ep-w.yaml
    

    访问测试一下看是否连通:这个返回501是没问题的。

    [root@k8s-master01 ~]# curl 10.110.144.61 -I
    HTTP/1.1 501 Not Implemented
    Server: Tengine
    Date: Mon, 14 Feb 2022 01:39:16 GMT
    Content-Type: text/html
    Content-Length: 583
    Connection: close
    

    4.Service反代外部域名

    Service的yaml文件:

    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: nginx-svc-wname
      name: nginx-svc-wname
    spec:
      type: ExternalName
      externalName: www.baidu.com
    

    然后创建就行了:

    # kubectl apply -f nginx-svc-wname.yaml
    

    5.Service 的类型:

    ClusterIP:在集群内部使用,默认
    ExternalName:通过返回定义的CNAME别名
    NodePort:在所有安装了kube-proxy的节点上打开一个端口,此端口可以代理至后端Pod,然后集群外部可以使用节点的IP地址和NodePort端口号访问到集群Pod服务。端口取值范围默认30000-32767
    LoadBalancer:使用云服务商提供的负载均衡器公开服务

    (三) Ingress(七层路由机制)

    1.Ingress概念:

    通俗来讲:Ingress和之前说的Service、Deployment一样,也是一个k8s的资源类型;Ingress用于实现域名的方式访问k8s的内部应用,Service可能更适于服务间访问。
    ingress我们一般使用的k8s官方维护的版本,另外nginx官方也有一个版本,怎么用看分具体的用户。
    Ingress支持多种方案:包括 Nginx、Haproxy、Traefik、istio等;在实际中Ingress上面可能还有一层公司的硬件层代理。
    大概的流程图如下:


    2.创建一个Ingress:

    这里ingress使用Hlem方式创建,后面再详细介绍,此处暂时直接使用。
    先准备如下资源:
    A:Ingress-nginx使用的两个容器镜像下载地址:
    B:镜像地址:registry.cn-hangzhou.aliyuncs.com
    C:镜像:yyangs/ingress-nginx-controller;yyangs/ingress-nginx-kube-webhook-certgen
    chart包链接:ingress-nginx-4.0.17
    首先先创建一个Helm(因为要使用helm创建)

    [root@k8s-master01 ~]# wget https://get.helm.sh/helm-v3.8.0-linux-amd64.tar.gz
    [root@k8s-master01 ~]# tar xf helm-v3.8.0-linux-amd64.tar.gz
    [root@k8s-master01 ~]# mv linux-amd64/helm /usr/local/bin/helm
    

    创建一个仓库 ,方便安装ingress:ingress的APP VERSION版本最好要大于0.35,查看其下可用的包

    [root@k8s-master01 ~]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
    "ingress-nginx" has been added to your repositories
    [root@k8s-master01 ~]# helm repo list
    NAME  URL                                      
    ingress-nginx https://kubernetes.github.io/ingress-nginx
    [root@k8s-master01 ~]# helm search repo ingress-nginx
    NAME  CHART VERSION APP VERSION DESCRIPTION                                      
    ingress-nginx/ingress-nginx 4.0.17  1.1.1 Ingress controller for Kubernetes using NGINX a...
    

    下载ingress包,将包解压到一个创建的目录中方便修改配置

    [root@k8s-master01 ~]# helm pull ingress-nginx/ingress-nginx
    ingress-nginx-4.0.17.tgz
    [root@k8s-master01 ~]# mkdir /temp
    [root@k8s-master01 ~]# mv ingress-nginx-4.0.17.tgz /temp/
    [root@k8s-master01 ~]# cd /temp/
    [root@k8s-master01 temp]# tar xf ingress-nginx-4.0.17.tgz
    

    进到ingress-nginx目录

    [root@k8s-master01 temp]# cd ingress-nginx/
    

    修改values.yaml,基本每一行都代表一个位

    # 源位置
    controller:
     name: controller
     image:
     registry: registry.cn-hangzhou.aliyuncs.com
     image: yyangs/ingress-nginx-controller
     ## digest: sha256:0bc88eb15f9e7f84e8e56c14fa5735aaa488b840983f87bd79b1054190e660de
    # dns策略
     dnsPolicy: ClusterFirstWithHostNet
    # 使用宿主机端口号,性能好
     hostNetwork: true
    # 资源类型选择DaemonSet,会在指定节点上部署
     kind: DaemonSet
    # 在有标签的node上部署
     nodeSelector:
     kubernetes.io/os: linux
     ingress: "true"
    # 类型,本地环境使用
     type: ClusterIP
    # 最后位置的另一处源位置
     patch:
     enabled: true
     image:
     registry: registry.cn-hangzhou.aliyuncs.com
     image: yyangs/ingress-nginx-kube-webhook-certgen
     ## digest: sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
    

    对上面的修改做一些说明:
    镜像源:他默认源是国外的,我们访问不到。所以我替换成了我的阿里源,如果做这个实验的小伙伴可以用我的源;最后一处的源也一样;注意把校验注释
    使用hostNetwork: true创建,配合资源类型选择DaemonSet性能更好
    dns策略:如果使用hostNetwork,策略需要改成dnsPolicy: ClusterFirstWithHostNet

    执行yaml文件创建

    # 创建一个命名空间
    [root@k8s-master01 ingress-nginx]# kubectl create ns ingress-nginx
    namespace/ingress-nginx created
    
    # 因为要在指定node上创建,所以给一台机器创建一个标签
    [root@k8s-master01 ingress-nginx]# kubectl label nodes k8s-master03 ingress=true
    node/k8s-master03 labeled
    # 执行helm创建,那个名称自定义,之前出了一点问题,所以换个名字。
    [root@k8s-master01 ~]# cd /temp/ingress-nginx/
    [root@k8s-master01 ingress-nginx]# helm install nginx-ingress -n ingress-nginx .
    [root@k8s-master01 temp]# kubectl get pod -n ingress-nginx -o wide
    NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
    nginx-ingress-ingress-nginx-controller-lrs9s 1/1 Running 0 22h 192.168.10.4 k8s-master03 <none> <none>
    

    可以看到这个Pod已经起来了,并且部署在master03节点上,也就是有ingress=ture标签的节点上,这样对ingress进行扩容或缩容的时候就会方便很多。
    比如当你想扩容的时候只需要在想扩容的节点打上对应的标签,就会自动部署一个新的Pod,就像下面这条命令。

    # kubectl label node k8s-master02 ingress=true
    

    当我不想要这个Pod的时候,缩容也会比较简单,去掉标签就可以了,可以看出标签的强大之处,减号等于删除标签的意思。

    # kubectl label node k8s-master02 ingress-
    

    hostNetwork方式部署的ingress,会在宿主机启动一个进程,我们去部署Pod的节点看一下,

    [root@k8s-master03 ~]# ss -tpln | grep 80
    LISTEN 0 16384 192.168.10.4:2380 *:* users:(("etcd",pid=1703,fd=7))
    LISTEN 0 16384 *:80 *:* users:(("nginx",pid=106434,fd=19),("nginx",pid=106427,fd=19))
    LISTEN 0 16384 *:80 *:* users:(("nginx",pid=106433,fd=11),("nginx",pid=106427,fd=11))
    LISTEN 0 16384 [::]:80 [::]:* users:(("nginx",pid=106433,fd=12),("nginx",pid=106427,fd=12))
    LISTEN 0 16384 [::]:80 [::]:* users:(("nginx",pid=106434,fd=20),("nginx",pid=106427,fd=20))
    [root@k8s-master03 ~]# ps aux | grep nginx
    root 2622 0.0 0.1 8852 5456 ? Ss 01:12 0:00 nginx: master process nginx -g daemon off;
    101 2759 0.0 0.0 9272 2456 ? S 01:12  0:00 nginx: worker process
    101 2760 0.0 0.0 9272 2456 ? S 01:12 0:00 nginx: worker process
    root 25605 0.0 0.0 112840 2292 pts/0 S+ 15:19 0:00 grep --color=auto nginx
    101 106347 0.0 0.0 208 4 ? Ss 09:08 0:00 /usr/bin/dumb-init -- /nginx-ingress-controller --publish-service=ingress-nginx/nginx-ingress-ingress-nginx-controller --election-id=ingress-controller-leader --controller-class=k8s.io/ingress-nginx --ingress-class=nginx --configmap=ingress-nginx/nginx-ingress-ingress-nginx-controller --validating-webhook=:8443 --validating-webhook-certificate=/usr/local/certificates/cert --validating-webhook-key=/usr/local/certificates/key
    101 106359 0.1 1.1 743048 44956 ? Ssl 09:08 0:25 /nginx-ingress-controller --publish-service=ingress-nginx/nginx-ingress-ingress-nginx-controller --election-id=ingress-controller-leader --controller-class=k8s.io/ingress-nginx --ingress-class=nginx --configmap=ingress-nginx/nginx-ingress-ingress-nginx-controller --validating-webhook=:8443 --validating-webhook-certificate=/usr/local/certificates/cert --validating-webhook-key=/usr/local/certificates/key
    101 106427 0.0 0.9 145100 36332 ? S 09:08 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /etc/nginx/nginx.conf
    101 106433 0.0 1.0 157128 40848 ? Sl 09:08 0:06 nginx: worker process
    101 106434 0.0 1.0 157128 41000 ? Sl 09:08 0:07 nginx: worker process
    101 106435 0.0 0.7 143072 29120 ?  S 09:08 0:00 nginx: cache manager process
    

    3.Ingress使用

    运行之后,接下来尝试简单的使用:
    传统架构中发布服务,需要配置修改nginx的配置文件;在k8s中ingress与其他资源类型一样,通过yaml去声明一个ingress的实例。
    官方网址:ingress-controller官方文档详细内容可以看这。
    使用官网上一个例子先认识一下ingress

    # vim ingress.yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
      name: example
    spec:
      ingressClassName: nginx
      rules:  # 可以配置多个rules
      - host: foo.bar.com # 域名匹配
        http:
          paths:  # 相当于nginx的location配合,同一个host可以配置多个paths
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-svc # 代理的哪个svc
                port: 
                  number: 80
    

    这里说一下上面这个实例的一些说明:
    从rules开始向下是定义前后端连接的规则:
    host:代表基于域名访问,客户端通过这个域名访问后端资源
    http.paths:相当于nginx的location中匹配规则
    pathType:Prefix:路径类型,路径由“/”符号分隔为一个个元素,匹配规则为逐个元素进行前缀匹配,默认ImplementationSpecific,还有一种是Exact。
    backend:定义后端
    service下定义后端的地址,包括代理的svc和端口号

    4.Ingress使用问题排查

    [root@k8s-master01 ~]# kubectl create -f ingress.yaml
    Error from server (InternalError): error when creating "ingress.yaml": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": failed to call webhook: Post "https://ingress-nginx-controller-admission.ingress-nginx.svc:443/networking/v1/ingresses?timeout=10s": service "ingress-nginx-controller-admission" not found
    

    创建的时候报错:yaml": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes. io"这个。
    查看了下网上说应该是删除之前创建的资源时没删干净。

    [root@k8s-master01 ~]# kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io
    NAME WEBHOOKS AGE
    ingress-nginx-admission 1 3d
    

    然后查看下果然有个ingress-nginx-admission,删除后在创建就成功了

    [root@k8s-master01 ~]# kubectl delete -A validatingwebhookconfigurations.admissionregistration.k8s.io ingress-nginx-admission
    validatingwebhookconfiguration.admissionregistration.k8s.io "ingress-nginx-admission" deleted
    

    执行ingress.yaml文件,这次就创建成功了。

    [root@k8s-master01 ~]# kubectl create -f ingress.yaml
    ingress.networking.k8s.io/exmple created
    [root@k8s-master01 ~]# kubectl get ingress
    NAME CLASS HOSTS ADDRESS PORTS AGE
    exmple <none> foo.bar.com 80 10m
    

    5.ingress配置多域名

    Ingress配置多域名,其实就是增加一个host实例。

    # 第一个域名
      - host: foo.bar.com 
        http:
          paths:  
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-svc
                port: 
                  number: 80
    # 第二个域名
      - host: foo2.bar.com 
        http:
          paths:  
          - path: /test
            pathType: Prefix
            backend:
              service:
                name: nginx-svc-2
                port: 
                  number: 80
    

    然后更新yaml文件就好了

    [root@k8s-master01 ~]# kubectl replace -f ingress.yaml
    

    (四) Helm(Kubernetes软件包管理器)

    1.Helm是什么?

    Helm是Kubernetes的软件包管理器,类似于yum、apt等包管理工具一样,Helm可以轻松的一键式部署出我们想要的应用。
    编写Helm有三个主要目标:
    A.轻松地实现从“从零到Kubernetes”;
    B.提供与操作系统类似的软件包管理系统;
    B.强调将应用程序部署到Kubernetes的安全性和可配置性。

    2.Helm中一个很重要的元素:Chart

    chart是Helm的软件包,是航海图的意思。chart是遵循chart规范的一组文件和目录,用于定义要安装到kubernetes中的资源。
    chart中包含一个名为chart.yaml的文件,它描述了此chart的版本、名称、说明和作者的一些信息。
    chart包含模板,即kubernetes清单。
    chart中有一个提供默认配置的文件名字为values.yaml。此文件包含安装和升级期间可覆盖的参数,可以进行修改。
    当你所见到一个chart的时候,它可能是一个压缩包,像这个样子ingress-nginx-4.0.17.tgz,也可以是一个目录ingress-nginx。
    它的目录构造可能是这个样子:

    [root@k8s-master01 ingress-nginx]# ls
    CHANGELOG.md Chart.yaml ci OWNERS README.md README.md.gotmpl templates values.yaml
    

    Chartan安装流程
    当一个chart被安装时,它的流程可能是这个样子的:
    Helm读取chart
    将定义的值发送到模板,生成kubernetes清单
    清单被发送到kubernetes
    kubernetes根据清单在集群中创建请求的资源

    3.使用Helm

    Helm拥有v2和v3版本,这里就忽略v2了,因为我是用的是v3。
    Helm提供了一个名为helm的命令行工具,我们使用它进行操作。
    安装helm客户端注意点
    安装helm时要注意一点,helm的版本要匹配kubernetes的版本,如下图:


    具体详细版本对应参考:https://helm.sh/docs/topics/version_skew/
    详细说明或其他方式安装参考:https://helm.sh/docs/intro/install/官方文档
    目前到我安装的时候helm的最新版本为3.8.0,而我的k8s集群版本为1.23.x是完全符合的。
    下载二进制包
    # wget https://get.helm.sh/helm-v3.8.0-linux-amd64.tar.gz
    

    解压二进制包

    # tar xf helm-v3.8.0-linux-amd64.tar.gz
    

    将解压后目录中的helm目录移动到/usr/local/bin/helm下

    # mv linux-amd64/helm /usr/local/bin/helm
    

    安装结束。
    添加chart存储库
    只有一个客户端工具是没法干活的,我们还需要知道它的chart包从哪来,相当于yum安装的软件源。
    添加一个官方存储库
    注意:add 后面的名称是自定义的,方便你记住,不是固定的

    # helm repo add bitnami https://charts.bitnami.com/bitnami
    # 我的环境添加的存储库
    [root@k8s-master01 ~]# helm repo list
    NAME  URL                                      
    ingress-nginx https://kubernetes.github.io/ingress-nginx
    nginx-stable  https://helm.nginx.com/stable            
    bitnami  https://charts.bitnami.com/bitnami   
    

    查看是否添加成功?其实上面已经演示了,这条命令可以查看你添加过的存储库存不存在

    # helm repo list
    

    搜索chart存储库
    添加了库后,怎么能知道我想安装的chart包存不存在呢?使用下面这条命令

    [root@k8s-master01 ~]# helm search repo apache
    NAME  CHART VERSION APP VERSION DESCRIPTION                                      
    bitnami/apache 9.0.2  2.4.52 Apache HTTP Server is an open-source HTTP serve...
    bitnami/airflow  12.0.1  2.2.3 Apache Airflow is a tool to express and execute...
    

    当然你也可以尝试搜索来自网络中的chart包:

    [root@k8s-master01 ~]# helm search hub wordpress
    URL  CHART VERSION  APP VERSION  DESCRIPTION                                      
    https://artifacthub.io/packages/helm/kube-wordp... 0.1.0  1.1  this is my wordpress package                     
    https://artifacthub.io/packages/helm/bitnami/wo... 13.0.11  5.9.0  WordPress is the world's most popular blogging ...
    

    4.安装一个chart

    安装chart的前提是需要有一个命名空间,当然默认的也可以,为了区分还是创建一个
    下面创建一个名为mysql的命名空间

    # kubectl create ns mysql
    

    然后安装chart软件包

    # hellm install my-mysql bitnami/mysql -n mysql
    

    说一下这条命令的含义:
    my-mysql代表我运行这个chart的名字,是自定义的
    bitnami/mysql:是存储库的名字加软件包名
    -n mysql:是指定命名空间的名字

    安装完可以查看一下是否安装成功:需要注意的是:
    不管你的Pod资源能不能创建成功,只要helm创建成功了那么这个实例就会存在
    同一命名空间内实例名称唯一,再次创建同名称的实例会报错

    [root@k8s-master01 ~]# helm list -n mysql
    NAME    NAMESPACE  REVISION UPDATED  STATUS  CHART  APP VERSION
    my-mysql mysql  1  2022-02-17 14:32:38.423267837 +0800 CST deployed mysql-8.8.23 8.0.28
    

    这条命令可以查看创建chart 的一些状态:

    [root@k8s-master01 ~]# helm status my-mysql -n mysql
    

    当不想要这个chart的时候也可以选择卸载掉:

    [root@k8s-master01 ~]# helm uninstall my-mysql -n mysql
    

    自定义配置安装
    默认安装的配置往往不是我们需要的,那么我们可以将chart包pull下来,然后进行修改参数后再执行。
    将chart包pull下来,进行解压,可以看到包内的基本信息

    [root@k8s-master01 ~]# helm pull bitnami/mysql
    [root@k8s-master01 ~]# tar xf mysql-8.8.23.tgz -C /temp/
    [root@k8s-master01 ~]# cd /temp/mysql/
    [root@k8s-master01 mysql]# ls
    Chart.lock charts Chart.yaml ci README.md templates values.schema.json values.yaml
    

    可以修改他的values.yaml文件,这里就不修改了
    然后执行修改后的values.yaml文件,因为你执行的是本地文件,就不用加源地址了

    [root@k8s-master01 mysql]# helm install mysql-01 -n mysql .
    

    如果你已经运行了这个chart,然后又修改了yaml文件,你可以用这条命令进行更新

    [root@k8s-master01 mysql]# helm upgrade --install mysql-01 -n mysql .
    

    这里只说一下helm的基本使用。以后会写chart的使用,自己创建chart等内容。

    相关文章

      网友评论

        本文标题:七 Kubernetes服务发布入门

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