入力を使用して、kubernetesクラスター内のポッドサービスを公開します

IngressおよびIngressControllerとは何ですか?

kubernetesクラスター内のサービスを外部に提供して、次の問題にアクセスします。

1.ポッドドリフトの問題

Kubernetesには強力なレプリカ制御機能があり、レプリカ(Pod)がハングしたときに他のマシンから新しいレプリカ(Pod)が自動的に開始され、動的に拡張することもできます。素人の言葉で言えば、このポッドはどのノードにも表示される可能性があります。いつでも、どのノードでもいつでも死ぬ可能性があります。ポッドが作成および破棄されると、ポッドIPは確実に動的に変化します。次に、この動的ポッドIPを公開する方法を教えてください。ここで、Kubernetesサービスメカニズムの助けを借りて、サービスはラベルの形式で指定されたラベルを持つポッドのグループを選択し、それらのポッドIPを監視して自動的にロードし、外部公開のためにサービスIPのみを公開します。これはNodePortモードです。次の図に示すように、各ノードでポートを開き、それを内部ポッドIPに転送します。

現時点でのアクセス方法:http:// nodeip :nodeport /

画像


2.ポート管理の問題

NodePortメソッドでサービスを公開する際の問題は、サービスが利用可能になると、各ノードでNodePortによって開かれるポートが非常に大きくなり、維持が困難になることです。現時点では、Nginxを使用して内部に直接転送できますか?ご存知のとおり、ポッドとポッドは相互に通信でき、ポッドはホストマシンのネットワーク名前空間を共有できます。つまり、ネットワーク名前空間を共有する場合、ポッドがリッスンするのはノード上のポートです。 。では、これはどのように達成できますか?簡単な実装では、DaemonSetを使用して各ノードの80を監視し、ルールを記述します。これは、Nginxがホストのポート80(NodePortと同様)にバインドされており、クラスター内にあるため、対応するノードに直接転送されるためです。次の図に示すように、サービスIPは以上です。

画像


3.ドメイン名の割り当てと動的更新の問題

上記の方法から、Nginx-Podを使用することで問題は解決したようですが、実際には大きな欠陥があります。新しいサービスが追加されるたびにNginx構成を変更する方法は?Nginxを使用すると、仮想ホストドメイン名によってさまざまなサービスを区別でき、各サービスはアップストリームを介してさまざまな負荷分散プールと、負荷分散のための場所のリバースプロキシを定義します。日常の使用では、nginxのみを変更する必要があります。達成された場合、K8Sでこのスケジューリング方法をどのように達成するのですか?バックエンドサービスの最初のサービスがecshopのみであり、bbsとメンバーサービスが後で追加されると仮定すると、スケジューリングのためにこれら2つのサービスをNginx-Podに追加するにはどうすればよいですか?フロントエンドのNginxポッドを毎回手動で変更したりローリングアップデートしたりすることはできません。このとき、Ingressが登場しました。上記のNginxを数えない場合、IngressにはIngressControllerとIngressの2つの主要なコンポーネントが含まれています。

画像

Ingressの簡単な理解は、最初にNginx構成を変更してから、さまざまなドメイン名が対応するサービスを構成する必要があるということです。次に、このアクションを抽象化してIngressオブジェクトに変換します。yamlで作成できます。Don '毎回Nginxを変更し、変更するだけです。yamlを作成/更新できます。問題は、「Nginxは何をすべきか」です。

IngressControllerは「Nginx処理メソッド」のソリューションです。IngressControolerはKubernetesAPIと対話して、クラスター内のIngressルールの変更を動的に認識し、それを読み取り、独自のテンプレートに従ってNginx構成の一部を生成します。それをNginxに書き込みますポッドで、最後にリロードします。ワークフローは次のとおりです。

画像

実際、IngressはKubernetes APIの標準リソースタイプの1つでもあります。実際には、DNS名(ホスト)またはURLパスに基づいて指定されたサービスリソースにリクエストを転送する一連のルールです。これは、クラスター外の要求トラフィックを、クラスター内で完了したサービス公開に転送するために使用されます。理解する必要があるのは、Ingressリソース自体は「トラフィックの侵入」を実行できないということです。これは単なるルールのコレクションです。これらのコレクションルールには、ソケットの監視やマッチングに応じたルーティングなど、他の機能の支援も必要です。転送では、Ingressリソースのソケットを監視し、トラフィックを転送できるこれらのコンポーネントは、IngressControllerです。

注:IngressコントローラーはDeploymentコントローラーとは異なり、Ingressコントローラーはkube-controller-managerの一部として直接実行されません。これは、CoreDNSと同様に、Kubernetesクラスターのアクセサリにすぎず、個別にデプロイする必要があります。クラスター上。


4.入力コントローラーとは何ですか?

Ingress Controllerは7層の負荷分散スケジューラです。クライアントのリクエストは最初にこの7層の負荷分散スケジューラに到着し、7層のロードバランサはプロキシをバックエンドポッドにリバースします。一般的な7層のロードバランサにはnginxとtraefikが含まれます。 、おなじみのnginxを例として取り上げます。リクエストがnginxに到着すると、アップストリームリバースプロキシを介してバックエンドポッドに転送されますが、バックエンドポッドのIPアドレスは常に変化するため、サービスが必要です。バックエンドポッドの前に追加されます。このサービスはグループ化の役割を果たすだけなので、アップストリームのサービスアドレスを入力するだけで済みます。

一般的な7層の負荷分散スケジューラは何ですか?

nginx:構成ファイルを手動でロードする必要があります

traefik:構成ファイルは、手動の介入なしに定期的に自動的にロードされます。この種のスケジューラーは、ほとんどの場合、マイクロサービスで使用されます。


5. Ingressとは何ですか?

公式:https//kubernetes.io/docs/concepts/services-networking/ingress/

Ingressの公式ウェブサイトの定義:ingresは、クラスターに入るリクエストをクラスター内の一部のサービスに転送できるため、サービスをクラスターの外部に公開できます。Ingressは、外部ネットワークからアクセスできるURLにクラスター内のサービスを構成し、トラフィックの負荷を分散し、ドメイン名アクセスに基づいて仮想ホストを提供できます。Ingressはk8sのリソースです。バックエンドポッドのIPアドレスが関連付けられている場合サービスの変更に伴い、変更されます。これらの変更は入力に保存され、入力によって7層の負荷分散スケジューラの入力コントローラに挿入されます。つまり、情報は7層の負荷分散スケジューラの構成ファイルに渡されます。構成を有効にするためにリロードすると、Ingressを使用してHTTP / Sリクエストを転送するサービスを指定できます。たとえば、リクエスト内のさまざまなホストとURLパスに従って、リクエストを別のサービスに分類できます。


6.要約:

入力コントローラー:

Ingress Controllerは、コントローラーとして理解できます。KubernetesAPIと継続的にやり取りして、追加や削除など、バックエンドサービスとポッドへのリアルタイムの変更を取得し、Ingressで定義されたルールに基づいて構成を生成します。次に、上記のNginxまたはtrafikロードバランサーを動的に更新し、構成を更新して有効にし、自動サービス検出の役割を果たします。

イングレス:

入力は、特定のドメイン名の要求がクラスター内の指定されたサービスに転送されるための定義ルールです。Yamlファイルを介して定義でき、1つ以上のサービスに対して1つ以上のIngressルールを定義できます。


7.7層の負荷分散スケジューラを使用する手順

(1)入力コントローラーをデプロイします。入力コントローラーはtraefikを使用します

(2)ポッドをグループ化するサービスを作成します

(3)ポッドアプリケーションを作成します。コントローラーからポッドを作成できます。

(4)入力httpを作成し、httpを介してk8s内部ポッドへのアクセスをテストします

(5)入力httpsを作成し、httpsを介してk8s内部ポッドへのアクセスをテストします


8.7層スケジューラを介してクライアントがバックエンドポッドにアクセスする方法

7層の負荷分散スケジューラ入力コントローラーを使用する場合、クライアントがkubernetesクラスター内のアプリケーションにアクセスすると、データパケットフローは次のプロセスのようになります。

クライアント---> Nodeip:port -----> IngressController ---> service ---> pod

画像

Ingressリソースを作成する方法

入力リソースは、HTTP仮想ホストまたはURLに基​​づく転送ルールです。これは転送ルールであることを強調しておく必要がありますこれは、リソース構成リストのspecフィールドにrules、backend、tlsなどのフィールドをネストすることによって定義されます。次の例では、転送ルールを含むIngressリソースが定義されています。tomcat.lucky.comに送信されたリクエストは、myappという名前のサービスリソースにプロキシされます。

apiVersion:extensions / v1beta1種類:Ingressメタデータ:名前:ingress-myapp名前空間:デフォルトのアノテーション:kubernetes.io/ingress.class: "nginx"仕様:ルール:-ホスト:tomcat.lucky.com http:パス:-パス:バックエンド:serviceName:myapp servicePort:80

Ingressのspecフィールドは、Ingressリソースのコアコンポーネントであり、主に次の3つのフィールドが含まれています。

ルール:現在のIngressリソースを定義するために使用される転送ルールのリスト。ルールがルールによって定義されている場合、またはルールが一致しない場合、すべてのトラフィックはバックエンドによって定義されたデフォルトのバックエンドに転送されます。

backend:默认的后端用于服务那些没有匹配到任何规则的请求;定义Ingress资源时,必须要定义backend或rules两者之一,该字段用于让负载均衡器指定一个全局默认的后端。

tls:TLS配置,目前仅支持通过默认端口443提供服务,如果要配置指定的列表成员指向不同的主机,则需要通过SNI TLS扩展机制来支持该功能。

backend对象的定义由2个必要的字段组成:serviceName和servicePort,分别用于指定流量转发的后端目标Service资源名称和端口。rules对象由一系列的配置的Ingress资源的host规则组成,这些host规则用于将一个主机上的某个URL映射到相关后端Service对象,其定义格式如下:

spec:  rules:  - hosts: <string>    http:      paths:      - path:        backend:          serviceName: <string>          servicePort: <string>

需要注意的是,.spec.rules.host属性值,目前暂不支持使用IP地址定义,也不支持IP:Port的格式,该字段留空,代表着通配所有主机名。tls对象由2个内嵌的字段组成,仅在定义TLS主机的转发规则上使用。

hosts:包含 于 使用 的 TLS 证书 之内 的 主机 名称 字符串 列表, 因此, 此处 使用 的 主机 名 必须 匹配 tlsSecret 中的 名称。

secretName: 用于 引用 SSL 会话 的 secret 对象 名称, 在 基于 SNI 实现 多 主机 路 由 的 场景 中, 此 字段 为 可选。

Ingress资源类型

Ingress的资源类型有以下4种:

1、单Service资源型Ingress2、基于URL路径进行流量转发3、基于主机名称的虚拟主机4、TLS类型的Ingress资源

单Service资源型Ingress

暴露单个服务的方法有多种,如NodePort、LoadBanlancer等等,当然也可以使用Ingress来进行暴露单个服务,只需要为Ingress指定default backend即可,如下示例:

apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: my-ingressspec:  backend:    serviceName: my-svc    servicePort: 80

Ingress控制器会为其分配一个IP地址接入请求流量,并将其转发至后端my-svc

Ingress Nginx部署

使用Ingress功能需要如下步骤:

1、安装部署ingress controller Pod2、部署后端服务3、部署ingress-nginx service4、部署ingress

1.安装Ingress Controller

1)把Ingress相关的yaml文件传到k8s的master节点的/root/test目录

mkdir /root/test

需要上传到这个目录下的yaml文件为

Ingress相关的yaml文件在百度网盘,地址如下:

链接:https://pan.baidu.com/s/1SF9Ni0CK0QmTFDEglmejiA 提取码:61co

2)创建ingress-nginx名称空间

kubectl apply -f namespace.yaml

3)创建ingress controller的pod

kubectl apply -f .

4)测试部署是否成功

kubectl get all -n ingress-nginx

显示如下,说明部署成功了:

NAME                                            READY   STATUS    RESTARTS   AGEpod/default-http-backend-78d75577fd-g4b8n       1/1     Running   0          3m2spod/nginx-ingress-controller-7c7d57b55d-ng2gr   1/1     Running   0          3m2s
NAME                           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGEservice/default-http-backend   ClusterIP   10.106.23.48   <none>        80/TCP    3m2s
NAME                                       READY   UP-TO-DATE   AVAILABLE   AGEdeployment.apps/default-http-backend       1/1     1            1           3m2sdeployment.apps/nginx-ingress-controller   1/1     1            1           3m2s
NAME                                                  DESIRED   CURRENT   READY   AGEreplicaset.apps/default-http-backend-78d75577fd       1         1         1       3m2sreplicaset.apps/nginx-ingress-controller-7c7d57b55d   1         1         1       3m2s

2.部署后端服务

1)部署后端服务

mkdir /root/test/ingress  && cd  /root/test/ingress

cat deploy-demo.yaml

apiVersion: v1kind: Servicemetadata:  name: myapp  namespace: defaultspec:  selector:    app: myapp    release: canary  ports:  - name: http    targetPort: 80    port: 80---apiVersion: apps/v1kind: Deploymentmetadata:  name: myapp-backend-pod  namespace: defaultspec:  replicas: 3  selector:    matchLabels:      app: myapp      release: canary  template:    metadata:      labels:        app: myapp        release: canary    spec:      containers:      - name: myapp        image: ikubernetes/myapp:v2        ports:        - name: http          containerPort: 80

2)更新yaml文件

kubectl apply -f deploy-demo.yaml

3)查看pod是否部署成功

kubectl get pods

显示如下,说明部署成功:

myapp-backend-pod-559ff5c66-6jgjs     1/1     Running   0          6smyapp-backend-pod-559ff5c66-fthgt     1/1     Running   0          6smyapp-backend-pod-559ff5c66-xtz6z     1/1     Running   0          6s


3.部署ingress-nginx service

通过ingress-controller对外提供服务,现在还需要手动给ingress-controller建立一个service,接收集群外部流量。方法如下:

1)下载ingress-controller的yaml文件

cat service-nodeport.yaml

apiVersion: v1kind: Servicemetadata:  name: ingress-nginx  namespace: ingress-nginx  labels:    app: ingress-nginxspec:  type: NodePort  ports:    - name: http      port: 80      targetPort: 80      protocol: TCP      nodePort: 30080    - name: https      port: 443      targetPort: 443      protocol: TCP      nodePort: 30443  selector:    app: ingress-nginx

2)创建ingress-controller的service

kubectl apply -f service-nodeport.yaml

查看service是否创建成功

kubectl get svc -n ingress-nginx

显示如下,说明创建成功:

ingress-nginx          NodePort    10.101.70.164   <none>        80:30080/TCP,443:30443/TCP   90s

3)浏览器访问ingress-controller的service

192.168.0.6:30080

注:192.168.0.6是k8s的master节点ip

此时应该是404 ,调度器是正常工作的,但是后端服务没有关联

画像

4.部署ingress

(1)编写ingress的配置清单

cat ingress-myapp.yaml

apiVersion: extensions/v1beta1          #api版本kind: Ingress           #清单类型metadata:                       #元数据  name: ingress-myapp    #ingress的名称  namespace: default     #所属名称空间  annotations:           #注解信息    kubernetes.io/ingress.class: "nginx"spec:      #规格  rules:   #定义后端转发的规则  - host: tomcat.lucky.com    #通过域名进行转发    http:      paths:             - path:       #配置访问路径,如果通过url进行转发,需要修改;空默认为访问的路径为"/"        backend:    #配置后端服务          serviceName: myapp          servicePort: 80


2)更新yaml文件

kubectl apply -f ingress-myapp.yaml

3)查看ingress-myapp的详细信息

kubectl describe ingress ingress-myapp

显示如下:

Name:             ingress-myappNamespace:        defaultAddress:          Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)Rules:  Host              Path  Backends  ----              ----  --------  tomcat.lucky.com                         myapp:80 (10.244.1.57:80,10.244.1.58:80,10.244.1.59:80)Annotations:        kubernetes.io/ingress.class: nginxEvents:  Type    Reason  Age   From                      Message  ----    ------  ----  ----                      -------  Normal  CREATE  44s   nginx-ingress-controller  Ingress default/ingress-myapp

4)修改本地host文件,下面的ip是k8s的master节点ip

192.168.0.6  tomcat.lucky.com

5)浏览器访问tomcat.lucky.com:30080

出现如下:

画像

5.部署ingress-测试代理tomcat服务

1)部署tomcat服务

cat tomcat-demo.yaml

apiVersion: v1kind: Servicemetadata:  name: tomcat  namespace: defaultspec:  selector:    app: tomcat    release: canary  ports:  - name: http    targetPort: 8080    port: 8080  - name: ajp    targetPort: 8009    port: 8009---apiVersion: apps/v1kind: Deploymentmetadata:  name: tomcat-deploy  namespace: defaultspec:  replicas: 3  selector:    matchLabels:      app: tomcat      release: canary  template:    metadata:      labels:        app: tomcat        release: canary    spec:      containers:      - name: tomcat        image: tomcat:8.5.34-jre8-alpine           ports:        - name: http          containerPort: 8080          name: ajp          containerPort: 8009


2)更新yaml文件

kubectl apply -f tomcat-demo.yaml

3)查看tomcat的pod是否部署成功

kubectl get pods

显示如下,说明创建成功:

tomcat-deploy-8655579b6c-5dfqw        1/1     Running   0          83stomcat-deploy-8655579b6c-9d79c        1/1     Running   0          83stomcat-deploy-8655579b6c-qmc62        1/1     Running   0          83s


4)编写tomcat的ingress规则,并创建ingress资源

cat ingress-tomcat.yaml

apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: tomcat  namespace: default  annotations:    kubernetes.io/ingress.class: "nginx"spec:  rules:  - host: tomcat.lucky6.com    #主机域名    http:      paths:      - path:        backend:          serviceName: tomcat          servicePort: 8080


更新yaml文件:

kubectl apply -f ingress-tomcat.yaml

修改本地host文件,下面的ip是k8s的master节点ip

192.168.0.6  tomcat.lucky6.com

5)浏览器访问tomcat.lucky6.com:30080

可看到出现如下界面:

画像

6)总结

从前面的部署过程中,可以再次进行总结部署的流程如下:

①下载Ingress-controller相关的YAML文件,并给Ingress-controller创建独立的名称空间;

②部署后端的服务,如myapp,并通过service进行暴露;

③部署Ingress-controller的service,以实现接入集群外部流量;

④部署Ingress,进行定义规则,使Ingress-controller和后端服务的Pod组进行关联。

构建TLS站点

(1)准备证书,在k8s的master节点操作

openssl genrsa -out tls.key 2048


openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=tomcat.lucky.com


(2)生成secret,在k8s的master节点操作

kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key


(3)查看secret

kubectl get secret

显示如下:

tomcat-ingress-secret   kubernetes.io/tls                     2      56s

(4)查看tomcat-ingress-secret详细信息

kubectl describe secret tomcat-ingress-secret


显示如下:


Name:         tomcat-ingress-secretNamespace:    defaultLabels:       <none>Annotations:  <none>Type:  kubernetes.io/tlsData====tls.key:  1679 bytestls.crt:  1294 bytes


(5)创建ingress

cat ingress-tomcat-tls.yaml

apiVersion:extensions / v1beta1kind:Ingressmetadata:name:ingress-tomcat-tls名前空間:デフォルトの注釈:kubernetes.io/ingress.class: "nginx" spec:tls:-hosts:-tomcat.lucky.com secretName:tomcat-ingress-シークレットルール:-ホスト:tomcat.lucky.com http:パス:-パス:バックエンド:serviceName:tomcat servicePort:8080


yamlファイルを更新します

kubectl apply -f ingress-tomcat-tls.yaml

(6)訪問テスト:

https://tomcat.lucky.com:30443/

上記はアクセスするのに最適なFirefoxブラウザであり、リスクを受け入れて続行することを選択すると、次のインターフェイスが表示されます

画像


おすすめ

転載: blog.51cto.com/15127502/2655043