https://www.cnblogs.com/dingbin/p/9754993.html
https://www.jianshu.com/p/feeea0bbd73e
https://www.jianshu.com/p/189fab1845c5
service 是 k8s 暴露http服务的默认方式, 其中 NodePort 类型可以将http 服务暴露在宿主机的端口上,以便外部可以访问。 service模式的结构如下.
service -> label selector -> pods
31217 -> app1 selector -> app1 1234
31218 -> app2 selector -> app2 3456
31218 -> app2 selector -> app2 4567
结构简单, 容易理解。
在service 之前加了一层ingress,结构如下
ingress -> service -> label selector -> podswww.app1.com -> app1-service -> app1 selector -> app1 1234
80 -> www.app2.com -> app2-service -> app2 selector -> app2 3456www.app3.com -> app3-service -> app3 selector ->app3 4567
我们以nginx-ingress 为例. 我们可以设置如下几个全局参数
这里只列出了部分, 更多请参考文档 https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/configmap.md
两种方式 configmap 和 custom template。 custom template 用来设置configmap不能设置的一些高级选项, 通常情况下,使用configmap 已经够用。
使用configmap 需要确保Ingress Controller时,启用了 configmap参数
我们以nginx-ingress 为例. 我们可以设置如下几参数
Ingress只能通过Annotations 进行设置。并且需要确保 Ingress Controller 启动时, 启用了 Annotations 选项
如此可以实现权限的隔离, 又可以提供配置能力 。
nginx-ingress 文档 https://github.com/kubernetes/ingress-nginx
kubernetes Ingess 是有2部分组成,Ingress Controller 和Ingress服务组成,常用的Ingress Controller 是ingress-nginx,工作的原理是:
Ingress Controller 会动态感知集群中的Ingress的规则变化,然后读取,动态生成Nginx的配置文件,最后注入到运行nginx的pod的中,然后会自动reload,配置生效。
用kubernetes Ingress 是由于它是7层调度,可以直接卸载https会话,代理的后端的pod可以直接使用明文的http协议。
而Service NodePort得类型,是4层得调度,做不到这点,然而现在https是一种趋势,所以在kubernetes 对外暴露服务得时候我们还是要选择Ingress。
vim default-backend.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: default-http-backend
labels:
k8s-app: default-http-backend
namespace: kube-system
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: default-http-backend
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
# Any image is permissable as long as:
# 1. It serves a 404 page at /
# 2. It serves 200 on a /healthz endpoint
#image: gcr.io/google_containers/defaultbackend:1.0
image: docker.io/cdchen/defaultbackend:1.0
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
nodeSelector:
kubernetes.io/hostname: k8s-produce-136
---
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
namespace: kube-system
labels:
k8s-app: default-http-backend
spec:
#type: NodePort
ports:
- port: 80
#nodePort: 8080
targetPort: 8080
selector:
k8s-app: default-http-backend
-------------------
cat nginx-ingress-controller.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress-controller
labels:
k8s-app: nginx-ingress-controller
namespace: kube-system
spec:
replicas: 1
template:
metadata:
labels:
k8s-app: nginx-ingress-controller
annotations:
prometheus.io/port: '10254'
prometheus.io/scrape: 'true'
spec:
# hostNetwork makes it possible to use ipv6 and to preserve the source IP correctly regardless of docker configuration
# however, it is not a hard dependency of the nginx-ingress-controller itself and it may cause issues if port 10254 already is taken on the host
# that said, since hostPort is broken on CNI (https://github.com/kubernetes/kubernetes/issues/31307) we have to use hostNetwork where CNI is used
# like with kubeadm
# hostNetwork: true
hostNetwork: true
terminationGracePeriodSeconds: 60
containers:
#- image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.10
- image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.9.0-beta.10
name: nginx-ingress-controller
readinessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 1
ports:
- containerPort: 80
hostPort: 80
- containerPort: 443
hostPort: 443
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
#- name: KUBERNETES_MASTER
# value: http://10.30.30.135:8080
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- --apiserver-host=http://10.30.30.135:8080
nodeSelector:
kubernetes.io/hostname: k8s-produce-136
-----------------------
cat jenkins-app.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jenkins
namespace: default
labels:
k8s-app: jenkins
spec:
replicas: 1
selector:
matchLabels:
k8s-app: jenkins
template:
metadata:
labels:
k8s-app: jenkins
spec:
containers:
- name: jenkins
image: hub.c.163.com/library/jenkins:latest
securityContext:
privileged: true
imagePullPolicy: IfNotPresent
volumeMounts:
- name: jenkins-home
mountPath: /var/jenkins_home
- name: maven-repository
mountPath: /opt/maven/repository
- name: docker
mountPath: /usr/bin/docker
- name: docker-sock
mountPath: /var/run/docker.sock
ports:
- containerPort: 8080
- containerPort: 50000
volumes:
- name: jenkins-home
hostPath:
path: /ceph/jenkins_home
- name: maven-repository
hostPath:
path: /ceph/maven/repository
- name: docker
hostPath:
path: /usr/bin/docker
- name: docker-sock
hostPath:
path: /var/run/docker.sock
nodeSelector:
kubernetes.io/hostname: k8s-produce-136
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: jenkins
name: jenkins
namespace: default
annotations:
prometheus.io/scrape: 'true'
spec:
ports:
- name: jenkins
port: 8081
#nodePort: 31888
targetPort: 8080
#- name: jenkins-agent
# port: 50000
# nodePort: 50000
# targetPort: 50000
#type: NodePort
selector:
k8s-app: jenkins
----------------
cat jenkins-ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jenkins-ingress
namespace: default #代理的服务是什么这个就是什么
annotations:
kubernetes.io/ingress.class: "nginx" #这里是说明ingress的类型使用的nginx,一定要说明这点,否则ingress Controller 不知道是配置成那种类型的配置文件
spec:
rules:
- host: ingress.jenkins.com
http:
paths:
- backend:
serviceName: jenkins #代理的后端的pod的service,通过这个service来生成nginx的upstrem
servicePort: 8081 #代理的后端的pod的service的port
/
表示若访问ingress.jenkins.com,则会将请求转发至jenkins 的service,端口为8081 。-----------------
这里是使用http访问的,如果要用https,首先我们要创建一个证书,步骤如下
1、openssl genrsa -out tls.key 2048
2、openssl req -new -x509 -key tls.key -out tls.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Hefei
Locality Name (eg, city) [Default City]:Hefei
Organization Name (eg, company) [Default Company Ltd]:test
Organizational Unit Name (eg, section) []:test
Common Name (eg, your name or your server's hostname) []:test.ding.com
Email Address []:
证书生成好了,然后把证书转成secret,
kubectl create secret tls ding-ingress-secret --cert=tls.crt --key=tls.key
修改下 jenkins-ingress.yml 加入刚刚添加的secret,修改后的文件如下:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jenkins-ingress
namespace: default #代理的服务是什么这个就是什么
annotations:
kubernetes.io/ingress.class: "nginx" #这里是说明ingress的类型使用的nginx,一定要说明这点,否则ingress Controller 不知道是配置成那种类型的配置文件
spec:
tls:
- hosts:
- test.ding.com
secretName: ding-ingress-secret
rules:
- host: ingress.jenkins.com
http:
paths:
- backend:
serviceName: jenkins #代理的后端的pod的service,通过这个service来生成nginx的upstrem
servicePort: 8081 #代理的后端的pod的service的port
总结下,部署ingress,首先要部署下后端代理的pod,这组pod必须要有service,service的作用是用于ingress规则代理到后端pod的,通俗点就是这个service仅仅是给这组pod分组的,没有其他的左右。接着部署Ingress Controller,最后是写ingress的规则,让Ingress Controller 发现注入到ingress-nginx的pod中生成配置文件