K8S简介
官网: https://kubernetes.io/
K8S的logo:
Docker的logo是一个大船,每一个容器像是一个集装箱一样装在船上面。
K8S就像一个舵一样,让用户能够在茫茫大海中将满载集装箱的大船驶向成功的彼岸。
前言
14年诞生,15年K8S发布了1.0版本,K8S已经成为了 云原生
时代的基础设施
云原生:应用都上了云之后,还是和原来本地部署运行之后的结果是一样的。
CNCF(Cloud Native Computing Foudation),2015年7月份底成立,属于linux基金会,初衷围绕“云原生”服务云计算,支持编排容器化微服务架构应用。
CNCF官网:http://cncf.io
K8S架构
pod:最小的可部署单元,一组(一个或多个)容器,这些容器共享存储、网络。
ReplicaSet :维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。
deployments:管理pod和replicaset
label:给某一个组件打上标签,以key/value的方式,例如打在pod上。
selector:在service层选择相同label的pod
service:具有相同Label功能的pod集合,label怎么知道这些pod有相同功能的呢,是通过selector。两个pod在k8s两个机器上面也可以组成service
node:在k8s集群中的一个worker机器
k8s集群组件
kubectl:跟k8s集群打交道的入口
认证/授权:每次通过kubectl命令跟集群打交道的时候,通过它去验证是否能执行该请求
apiserver:manager节点用来接收kubectl请求的
scheduler:策略,当kubectl的请求通过认证、授权之后,通过scheduler将该请求运行到哪个机器上
controller manager:分发请求
kube-proxy:每个节点接收controller的请求
kubelet:可以用来创建pod,
docker engine:pod里面是一个或多个container,所以要有docker环境的支撑
etcd:存储集群的数据
dashboard:监控整个集群的运行状态
dns:域名解析
安装K8S
系统环境准备
更新yum源
yum -y update
yum install -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp
设置每个机器的hosts文件
# master节点
hostnamectl set-hostname master
# worker1节点
hostnamectl set-hostname worker1
# worker2节点
hostnamectl set-hostname worker2
# 编辑hosts文件
vi /etc/hosts
# 把以下内容放进去
192.168.0.21 master
192.168.0.22 worker1
192.168.0.23 worker2
系统配置,每台机器分别执行以下命令
# (1)关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
# (2)关闭selinux
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
# (3)关闭swap
swapoff -a
sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab
# (4)配置iptables的ACCEPT规则
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat && iptables -P FORWARD ACCEPT
# (5)设置系统参数
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
安装kubeadm&kubelet&kubectl
配置yum源,添加阿里云仓库
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
kubeadm:创建k8s集群中的各个组件,如scheduler、controller manager等
kubelet:运行pod
kubectl:客户端通过它进行各种操作
查看kubeadm版本
yum list kubeadm --showduplicates | sort -r
# 这里我使用1.21.0-0版本
yum install -y kubeadm-1.21.0-0 kubelet-1.21.0-0 kubectl-1.21.0-0
docker和k8s设置同一个cgroup
# 编辑docker的daemon.json文件
vi /etc/docker/daemon.json
# 添加一下内容
"exec-opts": ["native.cgroupdriver=systemd"],
# 重启docker
systemctl restart docker
# kubelet,这边如果发现输出directory not exist,也说明是没问题的
sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
# 开机启动以下三个组件
systemctl enable kubelet && systemctl start kubelet
查看kubeadm使用的镜像版本
kubeadm config images list
### 显示以下几个组件的镜像
k8s.gcr.io/kube-apiserver:v1.21.0
k8s.gcr.io/kube-controller-manager:v1.21.0
k8s.gcr.io/kube-scheduler:v1.21.0
k8s.gcr.io/kube-proxy:v1.21.0
k8s.gcr.io/pause:3.4.1
k8s.gcr.io/etcd:3.4.13-0
k8s.gcr.io/coredns/coredns:v1.8.0
解决国外镜像不能访问的问题,创建 kubeadm.sh
脚本,用于拉取镜像/打tag/删除原有镜像
set -e
KUBE_VERSION=v1.21.0
KUBE_PAUSE_VERSION=3.4.1
ETCD_VERSION=3.4.13-0
CORE_DNS_VERSION=1.8.0
GCR_URL=k8s.gcr.io
ALIYUN_URL=registry.cn-beijing.aliyuncs.com/google_containers
images=(kube-proxy:${KUBE_VERSION}
kube-scheduler:${KUBE_VERSION}
kube-controller-manager:${KUBE_VERSION}
kube-apiserver:${KUBE_VERSION}
pause:${KUBE_PAUSE_VERSION}
etcd:${ETCD_VERSION}
coredns:${CORE_DNS_VERSION})
for imageName in ${images[@]} ; do
docker pull $ALIYUN_URL/$imageName
docker tag $ALIYUN_URL/$imageName $GCR_URL/$imageName
docker rmi $ALIYUN_URL/$imageName
done
运行脚本和查看镜像
# 运行脚本
sh ./kubeadm.sh
# 查看镜像
docker images
初始化K8S主节点
kubeadm官网:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
初始化主节点,在主节点执行以下命令
# --apiserver-advertise-address指定主节点ip,
kubeadm init --kubernetes-version=1.21.0 --apiserver-advertise-address=192.168.0.21 --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=all
# 注意:如果 192.168.0.0/16 已在您的网络中使用,您必须选择不同的 pod 网络 CIDR,替换上述命令中的 192.168.0.0/16,也就是使用--pod-network-cidr重新指定网段
kubeadm init做了以下几个事情
01-进行一系列检查,以确定这台机器可以部署kubernetes
02-生成kubernetes对外提供服务所需要的各种证书可对应目录
/etc/kubernetes/pki/*
03-为其他组件生成访问kube-ApiServer所需的配置文件
ls /etc/kubernetes/
admin.conf controller-manager.conf kubelet.conf scheduler.conf
04-为 Master组件生成Pod配置文件。
ls /etc/kubernetes/manifests/*.yaml
kube-apiserver.yaml
kube-controller-manager.yaml
kube-scheduler.yaml
05-生成etcd的Pod YAML文件。
ls /etc/kubernetes/manifests/*.yaml
kube-apiserver.yaml
kube-controller-manager.yaml
kube-scheduler.yaml
etcd.yaml
06-一旦这些 YAML 文件出现在被 kubelet 监视的/etc/kubernetes/manifests/目录下,kubelet就会自动创建这些yaml文件定义的pod,即master组件的容器。master容器启动后,kubeadm会通过检查localhost:6443/healthz这个master组件的健康状态检查URL,等待master组件完全运行起来
07-为集群生成一个bootstrap token
08-将ca.crt等 Master节点的重要信息,通过ConfigMap的方式保存在etcd中,工后续部署node节点使用
09-最后一步是安装默认插件,kubernetes默认kube-proxy和DNS两个插件是必须安装的
看到以下内容表示成功
若要重新初始化集群状态:kubeadm reset,然后再进行上述操作,
复制上面圈住的内容,在主节点执行,从节点执行的内容稍后执行
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
执行完之后可以看到该config文件
内容如下
查看运行的pods
# -n指定命名空间
kubectl get pods -n kube-system
发现coredns是在Pending状态,需要安装网络插件
也可以通过健康检查接口来验证
curl -k https://localhost:6443/healthz
# 会返回ok
此时万事具备,只欠东风,还需要一个网络插件,这里使用 calico
,可根据官网自行选择
calico网络插件
K8S网络插件官网地址:https://kubernetes.io/docs/concepts/cluster-administration/addons/
以下操作均在master节点执行
# 下载calico.yaml文件
wget https://docs.projectcalico.org/v3.9/manifests/calico.yaml
# 如果wget命令没有,可先安装wget命令,再去执行上面的命令
yum install -y wget
# 创建calico的pod
kubectl apply -f https://docs.projectcalico.org/v3.9/manifests/calico.yaml
# 再次查看pods
kubectl get pods -n kube-system
# 耐心等待几分钟,发现calico会创建并运行成功,coredns也会运行起来
### 如果不成功,使用以下方式解决
# 查看coredns状态,
kubectl describe pod coredns-558bd4d5db-8pmsh -n kube-system
# 可能会报Failed to pull image "k8s.gcr.io/coredns/coredns:v1.8.0": rpc error: code = Unknown desc = Error response from daemon: Get "https://k8s.gcr.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
# 可以发现它拉取的是 `k8s.gcr.io/coredns/coredns:v1.8.0` 这个镜像
# 给之前拉取的docker镜像重新打一个标签,让其绕行访问
#查看 coredns所在的镜像是否是报错提示里面去拉取的镜像
docker images
# 如果不是,重新打标签
docker tag k8s.gcr.io/coredns:1.8.0 k8s.gcr.io/coredns/coredns:v1.8.0
# 再次查看pods
kubectl get pods -n kube-system
# 会发现所有的pod都已经运行起来了
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-76bf499b46-x8mgs 1/1 Running 0 76m
calico-node-9hcms 1/1 Running 4 76m
coredns-558bd4d5db-8pmsh 1/1 Running 0 139m
coredns-558bd4d5db-s5n6q 1/1 Running 0 139m
etcd-master 1/1 Running 0 139m
kube-apiserver-master 1/1 Running 0 139m
kube-controller-manager-master 1/1 Running 0 139m
kube-proxy-vcckb 1/1 Running 0 139m
kube-scheduler-master 1/1 Running 0 139m
从节点加入主节点
# 分别在worker1和worker2两个节点执行
kubeadm join 192.168.0.21:6443 --token z4oguc.2w0ddkvdof2vhf4j \
--discovery-token-ca-cert-hash sha256:b0bf6cca68535a769ad7f9bda1d1b645a0e1c114d0a8188a13e2e4a5542081e5
# 显示以下内容加入成功
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
# 在master节点查看
kubectl get nodes
# 会发现两个从节点的Status由最开始的NotReady变为Ready
NAME STATUS ROLES AGE VERSION
master Ready control-plane,master 144m v1.21.0
worker1 Ready <none> 2m48s v1.21.0
worker2 Ready <none> 55s v1.21.0
K8S初体验
pod体验创建一个nginx的pod
创建nginx所需要的yaml文件 pod_nginx_rs.yaml
cat > pod_nginx_rs.yaml <<EOF
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx
labels:
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
name: nginx
labels:
tier: frontend
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
EOF
根据文件创建pod
kubectl apply -f pod_nginx_rs.yaml
查看pod
kubectl get pods
kubectl get pods -o wide
# 查看日志
kubectl describe pod nginx
# 删除该pod
kubectl delete -f pod_nginx_rs.yaml
再次创建一个pod
yaml配置文件,创建 nginx_pod.yaml
文件
# yaml格式对于Pod的定义:
apiVersion: v1 #必写,版本号,比如v1
kind: Pod #必写,类型,比如Pod
metadata: #必写,元数据
name: nginx #必写,表示pod名称
namespace: default #表示pod名称属于的命名空间
labels:
app: nginx #自定义标签名字
spec: #必写,pod中容器的详细定义
containers: #必写,pod中容器列表
- name: nginx #必写,容器名称
image: nginx #必写,容器的镜像名称
ports:
- containerPort: 80 #表示容器的端口
根据上面文件内容创建pod
kubectl apply -f nginx_pod.yaml
K8S组件
ReplicationController
可以确保指定数量的pod副本同时在运行。 换句话说,ReplicationController确保一个或一组相同的pods始终处于可用状态。
RC的selector是精确匹配的,如果labels里面没有selector定义的,创建pod的时候就会报错
创建 nginx_rc.yaml
文件
apiVersion: v1
kind: ReplicationController # 声明为rc
metadata:
name: nginx
spec:
replicas: 3
selector: # rc的selector一定要和labels对应上
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
根据 nginx_rc.yaml
文件创建nginx的pod
kubectl apply -f nginx_rc.yaml
查看pod
kubectl get pods -o wide
####################
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-4r89g 1/1 Running 0 3m22s 192.168.235.131 worker1 <none> <none>
nginx-4wlgb 1/1 Running 0 3m22s 192.168.189.68 worker2 <none> <none>
nginx-j5r6c 1/1 Running 0 3m22s 192.168.235.130 worker1 <none> <none>
kubectl get rc
################
NAME DESIRED CURRENT READY AGE
nginx 3 3 3 3m43s
删除一个pod
kubectl delete pods nginx-4r89g
再次查看
kubectl get pods
###################
NAME READY STATUS RESTARTS AGE
nginx-4wlgb 1/1 Running 0 5m12s
nginx-j5r6c 1/1 Running 0 5m12s
nginx-sstd7 1/1 Running 0 29
可以发现rc会自动进行扩容
扩缩容:kubectl scale rc nginx --replicas=5
ReplicaSet
在Kubernetes v1.2时,RC就升级成了另外一个概念:Replica Set,官方解释为“下一代RC”
ReplicaSet和RC没有本质的区别,kubectl中绝大部分作用于RC的命令同样适用于RS
RS与RC唯一的区别是:RS支持基于集合的Label Selector(Set-based selector),而RC只支持基于等式的Label Selector(equality-based selector),这使得Replica Set的功能更强。
一般情况下,我们很少单独使用Replica Set,它主要是被Deployment这个更高的资源对象所使用,从而形成一整套Pod创建、删除、更新的编排机制。当我们使用Deployment时,无须关心它是如何创建和维护Replica Set的,这一切都是自动发生的。同时,无需担心跟其他机制的不兼容问题(比如ReplicaSet不支持rolling-update但Deployment支持)。
Deployment
官网简介:https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
Deployment相对RC最大的一个升级就是我们可以随时知道当前Pod“部署”的进度。
创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建过程
检查Deploymnet的状态来看部署动作是否完成(Pod副本的数量是否达到预期的值)
创建 nginx_deployment.yaml
文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
根据 nginx_deployment.yaml
文件创建pod
kubectl apply -f nginx_deployment.yaml
查看pod
kubectl get pods
###################
NAME READY STATUS RESTARTS AGE
nginx-deployment-5d59d67564-26gtc 1/1 Running 0 119s
nginx-deployment-5d59d67564-8g29g 1/1 Running 0 119s
nginx-deployment-5d59d67564-clrdh 1/1 Running 0 119s
查看replicaset
kubectl get rs
##################
NAME DESIRED CURRENT READY AGE
nginx-deployment-5d59d67564 3 3 3 4m12s
查看deployment
kubectl get deployment
#######################
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 2m26s
# 查看详情
kubectl get deployment -o wide
#####################################
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 3/3 3 3 5m28s nginx nginx:1.7.9 app=nginx
更新nginx的image版本
kubectl set image deployment nginx-deployment nginx=nginx:1.9.1
Labels and Selectors
可以将具有同一个label的pod,交给selector管理
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector: # 匹配具有同一个label属性的pod标签
matchLabels:
app: nginx
template: # 定义pod的模板
metadata:
labels:
app: nginx # 定义当前pod的label属性,app为key,value为nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
查看pod的label标签:kubectl get pods --show-labels
Namespace
新建 myns-namespace.yaml
文件
apiVersion: v1
kind: Namespace
metadata:
name: myns
根据 myns-namespace.yaml
文件创建namespace
kubectl apply -f myns-namespace.yaml
查看namespace
kubectl get ns
# 或者
kubectl get namespace
新建 vi nginx_myns_pod.yaml
文件,并使用上面创建的namespace
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: myns
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
根据 vi nginx_myns_pod.yaml
创建pod
kubectl apply -f nginx_myns_pod.yaml
查看,需要指定命名空间
# 如果不带命名空间的参数,默认都是在default命名空间下的
kubectl get pods -n myns
# 查找所有命名空间的pod
kubectl get pods --all-namespaces
Network
pod中的container之间的通信:每个pod中都会有一个pause container,所有的创建的container都会连接到这个pause container上面
新建 nginx_pod.yaml
文件
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
新建 busybox_pod.yaml
文件
apiVersion: v1
kind: Pod
metadata:
name: busybox
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
将两个pod运行起来,并且查看运行情况
kubectl apply -f nginx_network_pod.yaml
kubectl apply -f busybox_pod.yaml
kubectl get pods -o wide
Service
Service类型:
-
ClusterIP:只能在集群内访问
-
NodePort:可以暴露到宿主主机上面,供外部访问
-
LoadBalancer:和nodeport类似,不过是采用公有云代理的来进行调度访问,类似nginx
-
ExternalName:把集群外部的服务引入到集群内部来使用
对于之前的Pod虽然实现了集群内部互相通信,但是Pod是不稳定的,比如通过Deployment管理Pod,随时可能对Pod进行扩缩容,这时候Pod的IP地址是变化的,动态扩容出来的pod会生成一个新的ip。能够有一个固定的IP,使得集群内能够访问。也就是之前在架构描述的时候所提到的,能够把相同或者具有关联的Pod,打上Label,组成Service。而Service有固定的IP,不管Pod怎么创建和销毁,都可以通过Service的IP进行访问。
集群内的service
创建 whoami-deployment.yaml
文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-deployment
labels:
app: whoami
spec:
replicas: 3
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: jwilder/whoami
ports:
- containerPort: 8000
创建whoami的pod
kubectl apply -f whoami-deployment.yaml
查看pod
kubectl get pods -o wide
# 显示以下内容
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
whoami-deployment-6fc5f56c44-4cgxq 1/1 Running 0 3m52s 192.168.235.130 worker1 <none> <none>
whoami-deployment-6fc5f56c44-t8vf6 1/1 Running 0 3m52s 192.168.189.67 worker2 <none> <none>
whoami-deployment-6fc5f56c44-vlpqs 1/1 Running 0 3m52s 192.168.189.68 worker2 <none> <none>
# 在集群的任意一台机器访问都可以成功
curl 192.168.235.130:8000/192.168.189.67:8000/192.168.189.68:8000
查看service
kubectl get svc
# 只有一个kubernetes名称的service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 158m
自定义service
创建一个whoami-deploment名称的service
kubectl expose deployment whoami-deployment
再次查看service
kubectl get svc
# 多了一个上面创建的
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 165m
whoami-deployment ClusterIP 10.107.220.147 <none> 8000/TCP 4s
# 访问10.107.220.147:8000可以达到负载均衡的效果
curl http://10.107.220.147:8000
可以对该pod进行扩容
kubectl scale deployment whoami-deployment --replicas=5
查看一下whoami-deployment的详情信息,发现有一个Endpoints连接了具体5个Pod
kubectl describe svc whoami-deployment
# 显示以下内容
Name: whoami-deployment
Namespace: default
Labels: app=whoami
Annotations: <none>
Selector: app=whoami
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.107.220.147
IPs: 10.107.220.147
Port: <unset> 8000/TCP
TargetPort: 8000/TCP
Endpoints: 192.168.189.67:8000,192.168.189.68:8000,192.168.189.69:8000 + 2 more...
Session Affinity: None
Events: <none>
# 直接查看endpoints
kubectl get endpoints
# 显示以下内容
NAME ENDPOINTS AGE
kubernetes 192.168.0.21:6443 3h3m
whoami-deployment 192.168.189.67:8000,192.168.189.68:8000,192.168.189.69:8000 + 2 more... 18m
删除service
kubectl delete service whoami-deployment
通过yaml文件创建service
创建 my-service.yaml
文件
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
type: ClusterIP
创建service
kubectl apply -f my-service.yaml
外部服务访问pod
还是基于之前的 whoami-deployment.yaml
文件创建pod,
kubectl apply -f whoami-deployment.yaml
然后创建 NodePort
类型的service
kubectl expose deployment whoami-deployment --type=NodePort
查看service
kubectl get svc
# 显示以下内容
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h37m
whoami-deployment NodePort 10.102.8.171 <none> 8000:30594/TCP 6s
# 30594就是映射到宿主主机的端口号
外部浏览器访问:三台节点的ip:30594
Service-LoadBalance
通常需要第三方云提供商支持,有约束性
Ingress
官网简介:https://kubernetes.io/docs/concepts/services-networking/ingress/
Ingress将来自集群外部的HTTP和HTTPS路由暴露给集群内的服务。 流量路由由Ingress资源上定义的规则控制。
入口可以配置为向服务提供外部可访问的url、负载均衡流量、终止SSL / TLS,并提供基于名称的虚拟主机。 入口控制器负责实现入口,通常使用负载均衡器,尽管它也可以配置你的边缘路由器或额外的前端来帮助处理流量。
入口不公开任意端口或协议。 将HTTP和HTTPS以外的服务公开到internet通常使用service类型的服务。
必须有一个入口控制器来满足入口。 仅创建Ingress资源无效。
你可能需要部署一个入口控制器,比如Ingress -nginx。 您可以从多个输入控制器中选择。
理想情况下,所有输入控制器应该符合参考规范。 在现实中,各种输入控制器的操作略有不同。
Ingress架构图:
这里选择Nginx Ingress Controller来实现,
Nginx Ingress Controller:https://kubernetes.github.io/ingress-nginx/deploy/
接下来使用nginx实现的ingress来进行代理
创建 my-tomcat.yaml
文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
labels:
app: tomcat
spec:
replicas: 1
selector:
matchLabels:
app: tomcat
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: tomcat
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: tomcat
# type: NodePort 下面我们使用HostPort方式运行
创建pod
kubectl apply -f my-tomcat.yaml
查看
kubectl get pods
kubectl get deployment
kubectl get svc
# 显示tomcat的service
tomcat-service NodePort 10.100.199.2 <none> 80:32381/TCP 3m56s
进入pod容器内更改webapps,不更改可能会有404的问题
kubectl exec -it tomcat-deployment-6c44f58b47-skxph /bin/bash
rm -rf webapps
cp -r webapps.dist/ webapps
上传 mandatory.yaml
文件,添加两个属性
spec:
template:
spec:
hostNetWork: true # 使用HostPort方式运行
nodeSelector: # 选择节点
name: ingress # 运行在标签名为ingress节点上
指定运行节点
kubectl label node worker1 name=ingress
创建pod
# 创建之前首先使用docker拉取一下下面这个镜像,比较耗时
docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
# 拉取完之后再创建pod,要确保w1节点上的80和443端口没有被占用
kubectl apply -f mandatory.yaml
查看运行状态
kubectl get pods -n ingress-nginx -o wide
# 显示运行在worker1节点上面
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ingress-controller-748d7f9c84-pb96f 1/1 Running 0 57s 192.168.0.22 worker1 <none> <none>
在worker1节点查看端口监听情况
lsof -i tcp:80
lsof -i tcp:443
# 可以发现监听了很多nginx的
查看
kubectl get svc
kubectl get pods
创建Ingress以及定义转发规则,编辑 nginx-ingress.yaml
文件
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
spec:
rules:
- host: k8singress.tianqingzhao.com # 使用域名访问
http:
paths:
- path: /
backend:
serviceName: tomcat-service
servicePort: 80
创建nginx-ingress的pod
kubectl apply -f nginx-ingress.yaml
查看
kubectl get ingress
kubectl describe ingress nginx-ingress
比如这里我使用的是k8singress.tianqingzhao.com这个域名,在域名厂商添加解析记录值。
如果没有域名,更改C:\Windows\System32\drivers\etc路径下的hosts文件,添加以下内容:
192.168.0.22 k8singress.tianqingzhao.com
浏览器访问:k8singress.tianqingzhao.com,显示成功
如果以后想要使用Ingress网络,其实只要定义ingress,service和pod即可,前提是要保证nginx ingress controller已经配置好了。