此文章是基于 kubernetes v1.19.7
版本写的
rbac
是rbac.authorization.k8s.io/v1
版本ingress
是networking.k8s.io/v1
版本
- 可以使用
kubectl api-versions
命令来查看自己当前的api
版本是否支持,不同的api
版本,yaml
文件内的字段使用会不一样
准备 yaml 文件
namespace.yaml
--- apiVersion: v1 kind: Namespace metadata: labels: name: ingress-nginx name: ingress-nginx
nginx-ingress-controller-sa.yaml
--- apiVersion: v1 kind: ServiceAccount metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx name: nginx-ingress-serviceaccount namespace: ingress-nginx
nginx-ingress-controller-rbac.yaml
--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx name: nginx-ingress-clusterrole rules: - apiGroups: - "" resources: - configmaps - endpoints - nodes - pods - secrets verbs: - list - watch - apiGroups: - "" resources: - nodes verbs: - get - apiGroups: - "" resources: - services verbs: - get - list - watch - apiGroups: - "" resources: - events verbs: - create - patch - apiGroups: - extensions - networking.k8s.io resources: - ingresses verbs: - get - list - watch - apiGroups: - extensions - networking.k8s.io resources: - ingresses/status verbs: - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx name: nginx-ingress-role namespace: ingress-nginx rules: - apiGroups: - "" resources: - configmaps - pods - secrets - namespaces verbs: - get - apiGroups: - "" resourceNames: - ingress-controller-leader-nginx resources: - configmaps verbs: - get - update - apiGroups: - "" resources: - configmaps verbs: - create - apiGroups: - "" resources: - endpoints verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx name: nginx-ingress-role-nisa-binding namespace: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: nginx-ingress-role subjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx name: nginx-ingress-clusterrole-nisa-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: nginx-ingress-clusterrole subjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx
nginx-ingress-controller-cm.yaml
--- apiVersion: v1 data: use-forwarded-headers: "true" kind: ConfigMap metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx name: nginx-configuration namespace: ingress-nginx
udp-service-cm.yaml
--- apiVersion: v1 kind: ConfigMap metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx name: udp-services namespace: ingress-nginx
tcp-service-cm.yaml
--- apiVersion: v1 kind: ConfigMap metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx name: tcp-services namespace: ingress-nginx
nginx-ingress-controller-ds.yaml
--- apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx name: ingress-nginx namespace: ingress-nginx spec: ports: - name: http port: 80 protocol: TCP targetPort: 80 - name: https port: 443 protocol: TCP targetPort: 443 selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx type: NodePort --- apiVersion: apps/v1 kind: DaemonSet metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx name: nginx-ingress-controller namespace: ingress-nginx spec: selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: containers: - args: - /nginx-ingress-controller - --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 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.26.1 lifecycle: preStop: exec: command: - /wait-shutdown livenessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 name: nginx-ingress-controller ports: - containerPort: 80 name: http - containerPort: 443 name: https - containerPort: 10254 name: metrics readinessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 securityContext: allowPrivilegeEscalation: true capabilities: add: - NET_BIND_SERVICE drop: - ALL runAsUser: 33 hostNetwork: true serviceAccountName: nginx-ingress-serviceaccount terminationGracePeriodSeconds: 30
部署 nginx-ingress-controller
kubectl apply -f namespace.yaml kubectl apply -f nginx-ingress-controller-sa.yaml kubectl apply -f nginx-ingress-controller-rbac.yaml kubectl apply -f nginx-ingress-controller-cm.yaml kubectl apply -f upd-service-cm.yaml kubectl apply -f tcp-service-cm.yaml kubectl apply -f nginx-ingress-controller-ds.yaml
配置 ingress 规则
- 准备一个 nginx 服务,如果已有,可以跳过这一步
- 这里配置了两个
service
,一个是ClusterIP
,一个是NodePort
,用来做对比cat <<EOF | kubectl apply -f - --- apiVersion: v1 kind: Service metadata: labels: app: nginx name: nginx-ingress spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: v1 kind: Service metadata: labels: app: nginx name: nginx-nodeport spec: type: NodePort selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-dp labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 EOF
- 查看
NodePort
端口,因为没有在 yaml 文件里面去指定端口 - 这里是方便学习,没有去指定
namespace
,实际使用的时候,一定要区分namespace
,不要去使用default
这个namespace
kubectl get svc
可以看到,暴露出来的端口是 32074
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 42h nginx-ingress ClusterIP 10.254.96.138 <none> 80/TCP 72s nginx-nodeport NodePort 10.254.87.143 <none> 80:32074/TCP 72s
通过 netstat
命令可以过滤到 32074
这个端口,并且是 kube-proxy
开放出来的,也可以去其他节点验证
netstat -anput | grep 32074
可以通过访问 ip:32074
来验证
curl -I 192.168.11.150:32074
返回状态码 200,表示成功
HTTP/1.1 200 OK Server: nginx/1.14.2 Date: Sat, 08 Jul 2023 10:00:07 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 04 Dec 2018 14:44:49 GMT Connection: keep-alive ETag: "5c0692e1-264" Accept-Ranges: bytes
在没有 ingress 规则的时候,我们去访问 80
端口是返回 404
的
curl -I 192.168.11.150
HTTP/1.1 404 Not Found Server: openresty/1.15.8.2 Date: Sat, 08 Jul 2023 10:01:11 GMT Content-Type: text/html Content-Length: 159 Connection: keep-alive
下面来配置 ingress 规则
cat <<EOF | kubectl apply -f - --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-study spec: rules: # host 字段不写,表示使用 ip 访问 ## host 字段可以写域名,如果没有 dns 解析,可以本地做 hosts 来验证 - host: http: paths: - backend: service: name: nginx-ingress port: number: 80 path: / pathType: Prefix EOF
这个时候就可以用 80
端口来验证了
curl -I 192.168.11.150
返回的状态码变成 200
了
HTTP/1.1 200 OK Server: openresty/1.15.8.2 Date: Sat, 08 Jul 2023 10:09:32 GMT Content-Type: text/html Content-Length: 612 Connection: keep-alive Vary: Accept-Encoding Last-Modified: Tue, 04 Dec 2018 14:44:49 GMT ETag: "5c0692e1-264" Accept-Ranges: bytes
使用域名的方式
cat <<EOF | kubectl apply -f - --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-study-domain spec: rules: # host 字段不写,表示使用 ip 访问 ## host 字段可以写域名,如果没有 dns 解析,可以本地做 hosts 来验证 - host: nginx.ingress.study http: paths: - backend: service: name: nginx-ingress port: number: 80 path: / pathType: Prefix EOF
增加本地 hosts
解析,这里拿 linux
举栗子
echo '192.168.11.150 nginx.ingress.study' >> /etc/hosts
这个时候去访问域名,一样可以返回 200
curl -I nginx.ingress.study
HTTP/1.1 200 OK Server: openresty/1.15.8.2 Date: Sat, 08 Jul 2023 10:14:07 GMT Content-Type: text/html Content-Length: 612 Connection: keep-alive Vary: Accept-Encoding Last-Modified: Tue, 04 Dec 2018 14:44:49 GMT ETag: "5c0692e1-264" Accept-Ranges: bytes
tcp-services 和 udp-services
通过
ingress-nginx-controller
来暴露本地的端口,通过不同的configmap
来指定端口的协议定义格式:<本机暴露的端口>: <service 的 namespace>/<需要转发的 service 的名字>:<需要转发的 service 的端口>
exposing-tcp-udp-services
cat <<EOF | kubectl apply -f - --- apiVersion: v1 kind: ConfigMap data: 8888: default/nginx-ingress:80 metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx name: tcp-services namespace: ingress-nginx EOF
使用 ip
访问 8888
端口,一样可以返回 200
curl -I 192.168.11.150:8888
HTTP/1.1 200 OK Server: nginx/1.14.2 Date: Sat, 08 Jul 2023 10:32:24 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 04 Dec 2018 14:44:49 GMT Connection: keep-alive ETag: "5c0692e1-264" Accept-Ranges: bytes