云原生

七 Kubernetes服务发布入门

2022-05-13  本文已影响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等内容。

上一篇下一篇

猜你喜欢

热点阅读