本篇重点讲解K8s中访问应用的几种方法,我将在k8s中布属一个nginx示例,示例将通过:hostNetwork,NodePort,Ingress方式来访问。
需要先准备K8s环境:《Kubernetes集群搭建》
示例一:通过hostNetwork,hostPort
[root@k8s-0001 nginx]# vi nginx.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx-test
labels:
name: nginx-test
namespace: develop
spec:
replicas: 1
selector:
name: nginx-test
template:
metadata:
labels:
name: nginx-test
namespace: develop
spec:
hostNetwork: true
containers:
- name: nginx-test
image: docker.io/nginx
ports:
- containerPort: 80
[root@k8s-0001 nginx]# kubectl get pods -n develop -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-test-ms852 1/1 Running 0 4m54s 192.168.1.85 k8s-0003
testapi-85664b498-vl749 1/1 Running 3 11d 10.244.2.42 k8s-0002
testapi-85664b498-zxqml 1/1 Running 11 11d 10.244.3.47 k8s-0004
[root@k8s-0001 nginx]# curl -i 192.168.1.85
HTTP/1.1 200 OK
Server: nginx/1.17.8
Date: Sat, 15 Feb 2020 06:06:15 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 21 Jan 2020 13:36:08 GMT
Connection: keep-alive
ETag: "5e26fe48-264"
Accept-Ranges: bytes
Welcome to nginx!
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
示例二:通过NodePort访问
apiVersion: v1
kind: Service
metadata:
name: nginx-test-svc
labels:
name: nginx-test-svc
namespace: develop
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
name: http
selector:
name: nginx-test
[root@k8s-0001 nginx]# kubectl get svc -n develop -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx-test-svc NodePort 10.102.30.135 80:32134/TCP 9m38s name=nginx-test
我们看到PORT(S)为80:32134 ,意思是该service对外暴露的端口是 32134并且该端口映身到了应用的80端口。当然,也可以通过nodePort属性来指定一个固定的端口,如下:
apiVersion: v1
kind: Service
metadata:
name: nginx-test-svc
labels:
name: nginx-test-svc
namespace: develop
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30011
name: http
selector:
name: nginx-test
[root@k8s-0001 nginx]# kubectl get svc -n develop -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx-test-svc NodePort 10.102.30.135 80:30011/TCP 9m38s name=nginx-test
示例三:通过Ingress访问
通过Ingress来访问应用,我们需要先搞清楚逻辑关系,我在搭建的时候走了一些弯路,是有些与想的不一样导致。
Ingress主要由三个部份组成:Ingress-service、Ingress-Controller、Ingress。
通过Ingress访问的逻辑为:Client Request -> Ingress-service(通过NodePort暴露端口) -> Ingress -> Service -> Deployment
开始布属,Ingress的yaml可以从以下链接获取最新,我们需要根据具体的情况,做一些修改。
https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.20.0/deploy/mandatory.yaml
apiVersion: v1
kind: Namespace
metadata:
name: develop
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: default-http-backend
labels:
app.kubernetes.io/name: default-http-backend
app.kubernetes.io/part-of: ingress-nginx
namespace: develop
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: default-http-backend
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: default-http-backend
app.kubernetes.io/part-of: ingress-nginx
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
# Any image is permissible as long as:
# 1. It serves a 404 page at /
# 2. It serves 200 on a /healthz endpoint
image: k8s.gcr.io/defaultbackend-amd64:1.5
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
ports:
- containerPort: 8080
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
---
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
namespace: develop
labels:
app.kubernetes.io/name: default-http-backend
app.kubernetes.io/part-of: ingress-nginx
spec:
ports:
- port: 80
targetPort: 8080
selector:
app.kubernetes.io/name: default-http-backend
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: develop
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: develop
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services
namespace: develop
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
namespace: develop
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
resources:
- ingresses/status
verbs:
- update
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: nginx-ingress-role
namespace: develop
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
resourceNames:
# Defaults to "-"
# Here: "-"
# This has to be adapted if you change either parameter
# when launching the nginx-ingress-controller.
- "ingress-controller-leader-nginx"
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: nginx-ingress-role-nisa-binding
namespace: develop
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress-role
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: develop
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nginx-ingress-clusterrole-nisa-binding
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nginx-ingress-clusterrole
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: develop
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: develop
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
serviceAccountName: nginx-ingress-serviceaccount
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.20.0
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
# www-data -> 33
runAsUser: 33
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: nginx-web
namespace: develop
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: findo.hixiu.com
http:
paths:
- path:
backend:
serviceName: findo-svc
servicePort: web
- host: gofindo.hixiu.com
http:
paths:
- path:
backend:
serviceName: go-findo-svc
servicePort: web
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress-controller
namespace: develop
spec:
type: NodePort
ports:
- name: http
port: 80
- name: https
port: 443
selector:
app.kubernetes.io/name: ingress-nginx
测试:通过 kubectl get svc -n develop -o wide 查看已布属的服务,可以发现nginx-ingress-controller 开发的端口为:30033
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
default-http-backend ClusterIP 10.102.58.113 80/TCP 9d app.kubernetes.io/name=default-http-backend,app.kubernetes.io/part-of=ingress-nginx
findo-svc ClusterIP 10.102.47.86 6660/TCP 9d webapi=findo-api
go-findo-svc ClusterIP 10.111.160.126 8080/TCP 19h webapi=go-findo-api
nginx-ingress-controller NodePort 10.101.0.193 80:30033/TCP,443:30241/TCP 9d app.kubernetes.io/name=ingress-nginx
testapi ClusterIP 10.108.208.200 8889/TCP 9d webapi=testwebapi
从ingress.yaml配置中不难看出我配置了两个字域名,分别访问不同的服务:go-findo-svc与findo-svc,对应的域名为:gofindo.hixiu.com与findo.hixiu.com,这两个服务分别是用Go与C#开发的,返回的类型不致,go返回的是json,C#返回的是text,我们来测试一下。