Service 類型
- ClusterIP 只在集群內部訪問,無法跨越集群邊界
- NodePort 提供集群外部流量進入到集群內部
- LoadBalancer 集群部署在公有雲或私有雲之上,提供給公有雲或私有雲的負載均衡中間使用
- ExternelName 把集群外部的服務映射給集群內部使用, 是一個FQDN的名稱,一個CNAME名稱,這個CNAM指向公網的FQDN
No ClusterIP 成為 Headless Sercie
ServiceName -> PodIP
Service 是一個四層調度器
也就是說,當請求為HTTPS請求的時候,則無法卸載證書。
namespace 名稱空間
;
創建 namespace 如下:
[root@master manifests]# kubectl create namespace dev
namespace/dev created
[root@master manifests]# kubectl get ns
NAME STATUS AGE
default Active 20d
dev Active 4s # 新創建的namespace
kube-node-lease Active 20d
kube-public Active 20d
kube-system Active 20d
刪除 namespace 如下:
[root@master manifests]# kubectl delete ns/dev
namespace "dev" deleted
[root@master manifests]# kubectl get ns
NAME STATUS AGE
default Active 20d
kube-node-lease Active 20d
kube-public Active 20d
kube-system Active 20d
Ingress Controller
舉例
當kubernetes集群有上千甚至跟多個節點的時候,此時需要特有的web七層代理
如在集群其中的四個節點上打上污點,這四個節點上只運行web七層代理所對應的Pod
由此Pod來代理集群內部的Service,Service再把流量轉發給集群內部對應的Pod。
這就叫做 Ingress Controller
Ingress Controller 是基於 DaemonSet 控制器來實現。
DaemonSet 是實現保證集群內部每個節點上都運行一個指定的Pod。
Kubernetes 中三種常用七層代理:
- Nginx # 常規代理
- Traefik # 微服務前段負載均衡
- Envoy # 微服務代理負載均衡,使用的多
Ingress
Ingress 和 Ingress Controller 是兩回事。
Ingress 原理
Ingress 啟動一個獨立的Pod來運行七層代理,可以是
Nginx、Traefik或者是Envoy,此時ingress Pod會直接代理 后端運行服務的Pod,為了能監聽后端Pod的變化,需要一個 無頭ServiceHeadless Sercie通過標簽選擇器來選擇后端指定的Pod,並收集到后端Pod對應的IP,而此Service不會被使用,它主要是用於被Ingress Pod來監聽后端Pod的變化,而一旦后端Pod產生變化,無頭Service 會知道,此時被Ingress Pod發現后,會自動根據變化來更改配置文件,並重載。
如果此時使用的是
Nginx類型的Ingress Pod,則每次變化后修改配置文件后都會自動重新 reload。
但如果使用Traefik或者是Envoy天生就是為微服務開發的,更友好的支持。

Ingress-nginx 進行測試
可以在 GitHub 上找到Ingress-nginx
本次使用的是相對簡單部署 ingress-nginx 的配置清單。
ingress-nginx 單獨的詳情頁面
因為是直接在物理機上直接安裝的kubernetes集群,所以需要兩個配置清單。
[root@master ingress]# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
還需要一個Ingress-name名稱空間中創建的NodePort Service,以便引入集群外流量
需要根據實際情況修改一下:
[root@master ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml
[root@master ingress]# cat service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
nodePort: 30080 # 手動指定node對外的http端口
- name: https
port: 443
targetPort: 443
protocol: TCP
nodePort: 30443 # 手動指定node對外的https端口
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
[root@master ingress]#kubectl apply -f service-nodeport.yaml
service/ingress-nginx created
查看創建的ingress-nginx Pod
[root@master ingress]# kubectl get pods -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ingress-controller-7995bd9c47-b4fzh 1/1 Running 0 34s 10.244.1.27 node03.kubernetes <none> <none>
[root@master ingress]# kubectl get svc -n ingress-nginx # 這里是第二次執行在Ingress-name名稱空間中創建的NodePort Service,以便引入集群外流量
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.111.201.108 <none> 80:30080/TCP,443:30443/TCP 44s
創建對應的后端Pod和Service
查看創建的ingress-myapp
[root@master ingress]# cat myapp-deplay.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp # Service 名稱
namespace: default
spec:
selector:
app: myapp
release: canary
ports:
- name: http
targetPort: 80 # 指定容器端口
port: 80 # Service 自己開房的端口
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
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
[root@master ingress]# kubectl apply -f myapp-deplay.yaml
service/myapp created
deployment.apps/myapp-deploy unchanged
查看
[root@master ingress]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-deploy-55b78d8548-b4c2c 1/1 Running 0 42h
myapp-deploy-55b78d8548-gpdw8 1/1 Running 0 42h
myapp-deploy-55b78d8548-hr6vx 1/1 Running 0 42h
[root@master ingress]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
myapp ClusterIP 10.111.44.7 <none> 80/TCP 6s
創建 Ingress
[root@master ingress]# cat ingress-myapp.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-myapp
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx" # 自動生成 nginx 相關的匹配和修改規則
spec:
rules:
- host: myapp.sijiayong.com # 使用 host 主機模式來訪問
http:
paths:
- path:
backend:
serviceName: myapp # 這里指定剛剛創建的后端Pod對應的Service名稱
servicePort: 80
[root@master ingress]# kubectl apply -f ingress-myapp.yaml
ingress.extensions/ingress-myapp created
[root@master ingress]# kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
ingress-myapp myapp.sijiayong.com 80 6s
查看 Ingress-controller 對應的Pod配置信息
上面一系列都配置完成之后,此時在看查看 Ingress-controller 的Pod中nginx的配置信息包含如下:
[root@master ingress]# kubectl exec -n ingress-nginx -it nginx-ingress-controller-7995bd9c47-b4fzh -- /bin/sh
server {
server_name myapp.sijiayong.com ;
listen 80;
set $proxy_upstream_name "-";
set $pass_access_scheme $scheme;
set $pass_server_port $server_port;
set $best_http_host $http_host;
set $pass_port $pass_server_port;
location / {
set $namespace "default";
set $ingress_name "ingress-myapp";
set $service_name "myapp";
set $service_port "80";
set $location_path "/";
... ...
... ...
訪問測試
此時在集群外部訪問測試:
注意,臨時測試,上面使用的host模式來訪問,所以在測試的集群外部機器上手動添加hosts記錄
[root@xinguan-test-node1 ~]# grep myapp /etc/hosts
10.0.20.20 myapp.sijiayong.com
[root@xinguan-test-node1 ~]# curl myapp.sijiayong.com:30080
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@xinguan-test-node1 ~]# curl myapp.sijiayong.com:30080/hostname.html
myapp-deploy-55b78d8548-hr6vx
模擬測試 Ingress 后端 Tomcat 訪問
還是基於上面的配置,一切都不動,增加tomcat后端Pod和Service 以及 Ingress
創建 tomcat 的 Pod 和Service
[root@master ingress]# cat tomcat-deploy.yaml
apiVersion: v1
kind: Service
metadata:
name: tomcat
namespace: default
spec:
selector:
app: tomcat
release: canary
ports:
- name: http
targetPort: 8080
port: 8080
- name: ajp
targetPort: 8009
port: 8009
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-depoly
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: tomcat
release: canary
template:
metadata:
labels:
app: tomcat
release: canary
spec:
containers:
- name: tomcat
image: tomcat:8.5.32-jre8-alpine
ports:
- name: http
containerPort: 8080
- name: ajp
containerPort: 8009
創建和查看
[root@master ingress]# kubectl apply -f tomcat-deploy.yaml
service/tomcat created
deployment.apps/tomcat-depoly created
[root@master ingress]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy-55b78d8548-b4c2c 1/1 Running 0 43h 10.244.3.29 node01.kubernetes <none> <none>
myapp-deploy-55b78d8548-gpdw8 1/1 Running 0 43h 10.244.1.26 node03.kubernetes <none> <none>
myapp-deploy-55b78d8548-hr6vx 1/1 Running 0 43h 10.244.2.22 node02.kubernetes <none> <none>
tomcat-depoly-579d97b849-66wrh 1/1 Running 0 7s 10.244.3.30 node01.kubernetes <none> <none>
tomcat-depoly-579d97b849-rh5r6 1/1 Running 0 7s 10.244.1.28 node03.kubernetes <none> <none>
tomcat-depoly-579d97b849-sd49w 1/1 Running 0 7s 10.244.2.23 node02.kubernetes <none> <none>
[root@master ingress]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d
myapp ClusterIP 10.111.44.7 <none> 80/TCP 76m
tomcat ClusterIP 10.106.39.78 <none> 8080/TCP,8009/TCP 3m18s
創建 tomcat-ingress
[root@master ingress]# cat ingress-tomcat.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-tomcat
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: tomcat.sijiayong.com
http:
paths:
- path:
backend:
serviceName: tomcat
servicePort: 8080
創建和查看
[root@master ingress]# kubectl apply -f ingress-tomcat.yaml
ingress.extensions/ingress-tomcat created
[root@master ingress]# kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
ingress-myapp myapp.sijiayong.com 80 53m
ingress-tomcat tomcat.sijiayong.com 80 4s
測試訪問 tomcat
注意,同樣寫Hosts 之后進行測試
[root@xinguan-test-node1 ~]# grep tomcat /etc/hosts
10.0.20.20 myapp.sijiayong.com tomcat.sijiayong.com
[root@xinguan-test-node1 ~]# curl tomcat.sijiayong.com:30080
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Apache Tomcat/8.5.32</title>
<link href="favicon.ico" rel="icon" type="image/x-icon" />
<link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />
<link href="tomcat.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="wrapper">
<div id="navigation" class="curved container">
<span id="nav-home"><a href="http://tomcat.apache.org/">Home</a></span>
<span id="nav-hosts"><a href="/docs/">Documentation</a></span>
<span id="nav-config"><a href="/docs/config/">Configuration</a></span>
<span id="nav-examples"><a href="/examples/">Examples</a></span>
<span id="nav-wiki"><a href="http://wiki.apache.org/tomcat/FrontPage">Wiki</a></span>
<span id="nav-lists"><a href="http://tomcat.apache.org/lists.html">Mailing Lists</a></span>
<span id="nav-help"><a href="http://tomcat.apache.org/findhelp.html">Find Help</a></span>
<br class="separator" />
</div>
<div id="asf-box">
<h1>Apache Tomcat/8.5.32</h1>
</div>
... ...
... ...
模擬測試 Https
模擬測試 通過Ingress 的七層代理,訪問Https,通過Ingress卸載證書后訪問后端
所有先需要手動自簽SSL證書
自簽SSL證書
[root@master https]# openssl genrsa -out tls.key 2048
Generating RSA private key, 2048 bit long modulus
...............................+++
.....................................................................................................................................+++
e is 65537 (0x10001)
[root@master https]# openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=BeiJing/L=BeiJing/O=DefOps/CN=tomcat.sijiayong.com
[root@master https]# ll
total 8
-rw-r--r-- 1 root root 1302 Aug 1 11:33 tls.crt
-rw-r--r-- 1 root root 1675 Aug 1 11:31 tls.key
自簽證書完成
創建secret
注意,此證書不能直接帖進去,需要先創建成secret,才能應用到Ingress中
[root@master https]# kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key
secret/tomcat-ingress-secret created
[root@master https]# kubectl get secret
NAME TYPE DATA AGE
default-token-bc86p kubernetes.io/service-account-token 3 22d
tomcat-ingress-secret kubernetes.io/tls 2 10s
[root@master https]# kubectl describe secret tomcat-ingress-secret
Name: tomcat-ingress-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/tls
Data
====
tls.key: 1675 bytes
tls.crt: 1302 bytes
創建tls的https清單文件
[root@master https]# cat ingress-tomcat-tls.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-tomcat-tls
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- tomcat.sijiayong.com
secretName: tomcat-ingress-secret # 這里指定剛剛創建的secret名稱
rules:
- host: tomcat.sijiayong.com
http:
paths:
- path:
backend:
serviceName: tomcat
servicePort: 8080
創建和查看
[root@master https]# kubectl apply -f ingress-tomcat-tls.yaml
ingress.extensions/ingress-tomcat-tls created
[root@master https]# kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
ingress-myapp myapp.sijiayong.com 80 174m
ingress-tomcat tomcat.sijiayong.com 80 121m
ingress-tomcat-tls tomcat.sijiayong.com 80, 443 4s # 這里看到被創建成功
[root@master https]# kubectl describe ingres-tomcat-tls
error: the server doesn't have a resource type "ingres-tomcat-tls"
[root@master https]# kubectl describe ingress ingress-tomcat-tls
Name: ingress-tomcat-tls
Namespace: default
Address:
Default backend: default-http-backend:80 (<none>)
TLS:
tomcat-ingress-secret terminates tomcat.sijiayong.com
Rules:
Host Path Backends
---- ---- --------
tomcat.sijiayong.com
tomcat:8080 (10.244.1.28:8080,10.244.2.23:8080,10.244.3.30:8080)
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-tomcat-tls","namespace":"default"},"spec":{"rules":[{"host":"tomcat.sijiayong.com","http":{"paths":[{"backend":{"serviceName":"tomcat","servicePort":8080},"path":null}]}}],"tls":[{"hosts":["tomcat.sijiayong.com"],"secretName":"tomcat-ingress-secret"}]}}
kubernetes.io/ingress.class: nginx
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 26s nginx-ingress-controller Ingress default/ingress-tomcat-tls
測試訪問
此時就已經完成,可以測試訪問
因前面測試hosts已經寫好

