目录
一. 直接访问Pod的IP地址
二. 通过Service访问
1. ClusterIP类型
2. NodePort类型
3. Ingress类型
Kubernetes中的最小单位是Pod,所有的应用也是运行在Pod中的
每个Pod都会被分配一个唯一的IP地址
创建一个Pod
cat nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
k8s-app: nginx-pod
name: nginx-pod
spec:
containers:
- image: 172.16.2.100:30050/library/nginx:latest
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
name: nginx
protocol: TCP
kubectl create -f nginx-pod.yaml
查看Pod的详细信息
[root@k8s-node1 example]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 26s 172.17.76.14 k8s-node2
可以看到该Pod分配一个IP地址,在另一个容器中可以正常访问该地址
[root@k8s-node1 ~]# kubectl --namespace=admin exec -it lnbkobka-session-jzqnd bash
[root@lnbkobka-session-jzqnd ~]# curl 172.17.76.14
Hello Nginx
(这种方式基本上不使用)
Pod的IP地址是一个随机分配的内网地址,只能在容器内部访问
并且正常场景下为了保证服务的可用性会通过deployment(statefulset)等来创建Pod,保证Pod的数量,而不会单独创建Pod
应为Pod是最小的单元如果在Pod中容器出现异常终止了是不会重启,在实际使用场景下基本不会直接使用Pod而是使用Deployment部署自己的应用
Deployment是对一组Pod集群的管理,可以保证环境中一直存在指定数量的Pod(比如当pod所在的node节点关机,则deployment会在其他节点重新启动Pod)
创建deployment
[root@k8s-node1 example]# cat nginx-dp.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
k8s-app: nginx-dp
name: nginx-dp
spec:
replicas: 2 // 表示当前deployment有2个副本
selector:
matchLabels:
k8s-app: nginx-dp
template:
metadata:
labels:
k8s-app: nginx-dp
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
name: nginx
protocol: TCP
查看deployment
[root@k8s-node1 example]# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-dp 2/2 2 2 8s
// 查看Pod信息
[root@k8s-node1 example]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-dp-78c4f884c8-qwh8m 1/1 Running 0 20s 172.17.86.12 k8s-node1
nginx-dp-78c4f884c8-sbvzz 1/1 Running 0 20s 172.17.76.14 k8s-node2
可以看到该Deployment下有2个Pod分别运行在两个Node节点上
手动删除一个Pod
[root@k8s-node1 example]# kubectl delete pod nginx-dp-78c4f884c8-qwh8m
pod "nginx-dp-78c4f884c8-qwh8m" deleted
[root@k8s-node1 example]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-dp-78c4f884c8-n4czv 1/1 Running 0 14s 172.17.86.12 k8s-node1
nginx-dp-78c4f884c8-sbvzz 1/1 Running 0 96s 172.17.76.14 k8s-node2
可以看到删除Pod后又自动创建了一个Pod(对于Deployment管理还可以进行Pod扩容,升级等操作)
从上面可以看到deployment只负责Pod的管理,本身并没有IP地址,但是deployment下会存在多个Pod,每个Pod的地址都不一样,如果存在扩容等操作后,扩容的Pod的地址也是随机生成的,不可能记住所有的Pod的地址
Kubernete Service 是一个定义了一组Pod的策略的抽象,我们也有时候叫做宏观服务。这些被服务标记的Pod都是(一般)通过label Selector决定的,举个例子,我们假设有一个tomcat的应用,通过deployment部署,有三个副本。对于需要调用tomcat服务的应用(比如nginx)来说,不需要关注这个tomcat有几个pod,而是通过一个固定的地址访问,当tomcat的pod发生变化时,nginx不需要关注,使用固定的地址仍然可用继续访问
Service根据使用方式有几种类型
创建一个service
[root@k8s-node1 example]# cat nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
ports:
- name: nginx
port: 80
protocol: TCP
targetPort: 80
selector:
k8s-app: nginx-dp
type: ClusterIP
[root@k8s-node1 example]# kubectl create -f nginx-svc.yaml
service/nginx-svc created
查看Service信息,可用看到service分配了一个cluster-ip
[root@k8s-node1 example]# kubectl get service nginx-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc ClusterIP 10.10.207.26 80/TCP 10s
在其他容器中访问clusterIP
[root@k8s-node1 ~]# kubectl --namespace=admin exec -it lnbkobka-session-jzqnd bash
[root@lnbkobka-session-jzqnd ~]# curl 10.10.207.26
Hello Nginx
可用看到通过clusterip访问也可以正常访问,但是clusterip仍然是内网IP,只能通过容器内部访问(也可以直接通过service-name访问,k8s内部会自动进行域名解析)
这种方式一般适用于不需要对外的服务,比如mysql,redis等
nodeport类型的service和clusterip相比多了一个nodeport属性,会在所有的node节点开放nodeport端口,通过访问物理机的端口达到访问容器的效果
创建nodeport类型的service(service yaml中可以手动定义nodeport,范围在30000-32767,不过这种方式容易冲突,不定义的话kubernetes会自动生成一个)
[root@k8s-node1 example]# cat nginx-svc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc-nodeport
spec:
ports:
- name: nginx
port: 80
protocol: TCP
targetPort: 80
selector:
k8s-app: nginx-dp
type: NodePort
[root@k8s-node1 example]# kubectl create -f nginx-svc-nodeport.yaml
service/nginx-svc-nodeport created
[root@k8s-node1 example]# kubectl get service nginx-svc-nodeport
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc-nodeport NodePort 10.10.133.76 80:32117/TCP 14s
查看service可以看到多了一个32117的端口,在物理机上查看该端口的状态,可以看到在监听中
[root@k8s-node1 example]# lsof -i:32117
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
kube-prox 27278 root 33u IPv6 120151742 0t0 TCP *:32117 (LISTEN)
在物理机上访问物理机IP:NodePort,可以看到在物理机上通过nodeport已经可以访问到容器的服务
[root@k8s-node1 example]# curl 127.0.0.1:32117
Hello Nginx
由于nodeport会在每个节点上进行监听,所以任意一个nodeip+nodeport都可以访问
在实际环境中,我们一般会使用keepalived对node节点做vip,通过vip访问,或者单独搭建一个nginx,通过nginx进行负载均衡