K8S利用Nginx-Ingress配置对外访问

#kubernetes

K8S 使用kubeadm 安装,版本为v1.14.3 环境介绍: 使用ingress转发请求至对应服务的pod上,对外提供统一的访问地址,

部署Ingress前,K8S集群需要有部署Ingress Controller,可以参考[[Kubernetes/K8S的Nginx-Ingress-Controller|Nginx Ingress Controller]]来部署

创建对外访问ingress示例

test-k8s-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress	# 名称必须
  namespace: kube-system	# 命名空间必须跟关联的服务为同一空间,不然无法访问到被代理的服务
  annotations: 
	nginx.ingress.kubernetes.io/rewrite-target: "/"	# 配置/path/这类URL需要开启rewriter重定向,不然无法访问/path/这类URL
spec:
  rules:
  - host: n.testnginx.com	# 对外提供访问的域名,留空则可以通过ingress-controller所在的NODE_IP来访问
	http: 
	  paths:
	  - path: /             # 定义不同的URL
		backend:
		  serviceName: test-k8s	# 服务名称
		  servicePort: 80

	  - path: /api/
		backend:
		  serviceName: api-test-k8s
		  servicePort: 8080

	host: www.abc.com       # 定义不同的域名
	http:
	  paths:
	  - path: /
		backend:
		  serviceName: www-k8s
		  servicePort: 80
	host:        # 不使用域名,可以直接使用任意ingress controller节点所在IP进行访问,不过默认禁用http,强制使用https访问。
	http:
	  paths:
	  - path: /
		backend:
		  serviceName: www-k8s-aaa
		  servicePort: 80

启动

kubectl apply -f test-k8s-ingress.yaml
kubectl get ingress	# 查看 ingress
kubectl describe ingress nginx-ingress -n kube-system	# 查看详细信息

使用SSL证书

# 生成证书或从CA机构获取
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=*.domain.com/O=nginxsvc"	

# 创建名称为tls-secret(可自定义名称)的secret对象
kubectl create secret tls tls-secret --key tls.key --cert tls.crt 

也可以使用cert-manager等工具实现自动颁发证书

编辑对外访问ingress配置

domain-ingress.yaml

	apiVersion: extensions/v1beta1
	kind: Ingress
	metadata:
	  name: nginx-ingress
	  namespace: kube-system
	  annotations: 
		nginx.ingress.kubernetes.io/rewrite-target: "/"
	spec:

	  # SSL配置开始
	  tls:
		- hosts:
		  - n.domain.com	# 指定域名
		  secretName: tls-secret	# 指定secret对象名称
	  # SSL配置结束
	  rules:
	  - host: n.domain.com
		http: 
		  paths:
		  - path: /test/
			backend:
			  serviceName: test-k8s
			  servicePort: 80

通过Ingress访问非K8S集群资源

有时为了控制服务访问统一的入口,会希望一些并非部署在K8S集群中的服务也通过Ingress来控制访问域名,也方便于利用cert-manager等工具对访问域名进行HTTPS配置、管理。

Ingress转发非集群内域名

正常情况下,Ingress中service字段处只能配置集群内部的资源,但可以通过Service的外部服务名称(ExternalName Service)功能来实现,它可以用来将内部服务名映射到外部域名上。你可以创建一个 ExternalName Service,将其 spec.type 设置为 ExternalName,并在 spec.externalName 中指定外部域名。

apiVersion: v1
kind: Service
metadata:
  name: my-external-service
spec:
  type: ExternalName
  externalName: example.com
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-external-service
            port:
              number: 80

限制: 在 Kubernetes 中,ExternalName 类型的 Service 是用来将集群内部的服务名称映射到外部的 DNS 名称的。ExternalName Service 的 spec.externalName 字段只接受一个 DNS 名称,不能包含端口或协议。ExternalName Service 的配置只能指定一个域名,不能包括端口号或协议(如 http:// 或 https://)。

Ingress转发非集群内IP资源

如果一个非集群的内部服务映射到一个外部 IP 地址进行访问,可以使用 Endpoints 资源加Service资源实现Ingress转发。

单个服务、单个端口配置

apiVersion: v1
kind: Service
metadata:
  name: my-external-service
spec:
  ports:
  - port: 8080
    protocol: TCP
---
apiVersion: v1
kind: Endpoints
metadata:
  name: my-external-service
subsets:
- addresses:
  - ip: 203.0.113.1  # 外部 IP 地址
  ports:
  - port: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-external-service
            port:
              number: 8080

多个服务、多个端口配置

apiVersion: v1
kind: Service
metadata:
  name: dev-gitlab-wiki-zentao-1
  namespace: pro-common
spec:
  ports:
  - name: port-80 # 这个名称要跟Endpoints资源中的名称一致
    port: 80
    targetPort: 80
  - name: port-81
    port: 81
    targetPort: 81
  - name: port-82
    port: 82
    targetPort: 82
  - name: port-3000
    port: 3000
    targetPort: 3000
---
apiVersion: v1
kind: Endpoints
metadata:
  name: dev-gitlab-wiki-zentao-1
  namespace: pro-common
subsets:
- addresses:
  - ip: 192.168.200.126
  ports:
  - name: prot-80 # 这个名称要跟Service资源中的名称一致
    port: 80
  - name: prot-81
    port: 81
  - name: prot-82
    port: 82
- addresses:
  - ip: 192.168.160.109
  ports:
  - name: prot-3000
    port: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: pro-common-dev-gitlab-wiki-zentao-1   # ingress 名称
  namespace: pro-common    # 命名空间,需要跟项目相同
spec:
  tls:
    - secretName: pro-common-dev-gitlab-wiki-zentao-1
    - hosts:
      - git.domain.com
      secretName: pro-common-dev-gitlab-wiki-zentao-1
    - hosts:
      - wiki.domain.com
      secretName: pro-common-dev-gitlab-wiki-zentao-1
    - hosts:
      - zentao.domain.com
      secretName: pro-common-dev-gitlab-wiki-zentao-1
    - hosts:
      - g.domain22.com
      secretName: pro-common-dev-gitlab-wiki-zentao-1
  rules:
    - host: git.domain.com
      http:
        paths:
          - path: /
            backend:
              service:
                name: dev-gitlab-wiki-zentao-1
                port:
                  number: 80
            property:
              ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
            pathType: ImplementationSpecific
    - host: wiki.domain.com
      http:
        paths:
          - path: /
            backend:
              service:
                name: dev-gitlab-wiki-zentao-1
                port:
                  number: 81
            property:
              ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
            pathType: ImplementationSpecific
    - host: zentao.domain.com
      http:
        paths:
          - path: /
            backend:
              service:
                name: dev-gitlab-wiki-zentao-1
                port:
                  number: 82
            property:
              ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
            pathType: ImplementationSpecific
    - host: g.domain22.com
      http:
        paths:
          - path: /
            backend:
              service:
                name: dev-gitlab-wiki-zentao-1
                port:
                  number: 3000
            property:
              ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
            pathType: ImplementationSpecific
  ingressClassName: nginx
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: pro-common-dev-gitlab-wiki-zentao-1
  namespace: pro-common
spec:
  secretName: pro-common-dev-gitlab-wiki-zentao-1
  issuerRef:
    name: letsencrypt-prod-dns01
    kind: ClusterIssuer
  dnsNames:
  - git.domain.com
  - zentao.domain.com
  - wiki.domain.com
  - g.domain22.com

最后更新于