(一) 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等内容。
网友评论