Service 对外暴露与应用
Service
Kubernetes Service定义了这样一种抽象:逻辑上的一组 Pod,一种能够访问它们的策略 —— 一般被称为微服务。这一组 Pod 可以被 Service 访问到,一般是经过 selector实现的。
举例:考虑一个图片处理 backend,它运行了3个副本。这些副本是可互换的 —— frontend 不需要关心它们调用了哪一个 backend 副本。 然而组成这一组 backend 程序的 Pod 实际上可能会发生变化,frontend 客户端不必知道,并且也不需要跟踪这一组 backend 的状态。Service 定义的抽象可以解耦这种关联。
Service能够提供负载均衡的能力,可是使用上存在以下限制:
- 只能提供4层负载均衡能力,而没有7层功能。有时咱们可能须要更多的匹配规则来转发请求,这点上4层负载均衡是不支持的、
如web访问的service服务示例图:
VIP和Service代理
在 Kubernetes 集群中,每一个 Node 运行一个 kube-proxy 进程。kube-proxy 负责为 Service 实现了一种 VIP(虚拟 IP)的形式,而不是 ExternalName 的形式。后端
从Kubernetes v1.0开始,已经可使用 userspace代理模式。Kubernetes v1.1添加了 iptables 代理模式,在 Kubernetes v1.2 中kube-proxy 的 iptables 模式成为默认设置。Kubernetes v1.8添加了 ipvs 代理模式。
为何不使用 DNS 轮询?
缘由以下:
-
DNS 实现的历史由来已久,它不遵照记录 TTL,而且在名称查找到结果后会对其进行缓存。
-
有些应用程序仅执行一次 DNS 查找,并没有限期地缓存结果。
-
即便应用和库进行了适当的从新解析,DNS 记录上的 TTL 值低或为零也可能会给 DNS 带来高负载,从而使管理变得困难。
由于有缓存,所以不合适。
userspace代理模式
这种模式,kube-proxy 会监视 Kubernetes master 对 Service 对象和 Endpoints 对象的添加和移除。 对每一个 Service,它会在本地 Node 上打开一个端口(随机选择)。 任何链接到“代理端口”的请求,都会被代理到 Service 的backend Pods 中的某个上面(如 Endpoints 所报告的同样)。 使用哪一个 backend Pod,是 kube-proxy 基于 SessionAffinity 来肯定的。网络
最后,它配置 iptables 规则,捕获到达该 Service 的 clusterIP(是虚拟 IP)和 Port 的请求,并重定向到代理端口,代理端口再代理请求到 backend Pod。
默认状况下,userspace模式下的kube-proxy经过循环算法选择后端。
默认的策略是,经过 round-robin 算法来选择 backend Pod。
iptables 代理模式
这种模式,kube-proxy 会监视 Kubernetes 控制节点对 Service 对象和 Endpoints 对象的添加和移除。 对每一个 Service,它会配置 iptables 规则,从而捕获到达该 Service 的 clusterIP 和端口的请求,进而将请求重定向到 Service 的一组 backend 中的某个上面。对于每一个 Endpoints 对象,它也会配置 iptables 规则,这个规则会选择一个 backend 组合。
默认的策略是,kube-proxy 在 iptables 模式下随机选择一个 backend。
使用 iptables 处理流量具备较低的系统开销,由于流量由 Linux netfilter 处理,而无需在用户空间和内核空间之间切换。 这种方法也可能更可靠。
若是 kube-proxy 在 iptables模式下运行,而且所选的第一个 Pod 没有响应,则链接失败。 这与userspace模式不一样:在这种状况下,kube-proxy 将检测到与第一个 Pod 的链接已失败,并会自动使用其余后端 Pod 重试。
咱们可使用 Pod readiness 探测器 验证后端 Pod 是否能够正常工做,以便 iptables 模式下的 kube-proxy 仅看到测试正常的后端。这样作意味着能够避免将流量经过 kube-proxy 发送到已知已失败的Pod。
IPVS 代理模式
在 ipvs 模式下,kube-proxy监视Kubernetes服务(Service)和端点(Endpoints),调用 netlink 接口相应地建立 IPVS 规则, 并按期将 IPVS 规则与 Kubernetes服务(Service)和端点(Endpoints)同步。该控制循环可确保 IPVS 状态与所需状态匹配。访问服务(Service)时,IPVS 将流量定向到后端Pod之一。
IPVS代理模式基于相似于 iptables 模式的 netfilter 挂钩函数,可是使用哈希表做为基础数据结构,而且在内核空间中工做。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通讯的延迟要短,而且在同步代理规则时具备更好的性能。与其余代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。
IPVS提供了更多选项来平衡后端Pod的流量。分别是:
- rr: round-robin
- lc: least connection (smallest number of open connections)
- dh: destination hashing
- sh: source hashing
- sed: shortest expected delay
- nq: never queue
注意:要在 IPVS 模式下运行 kube-proxy,必须在启动 kube-proxy 以前使 IPVS Linux 在节点上可用。 当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。 若是未检测到 IPVS 内核模块,则 kube-proxy 将退回到以 iptables 代理模式运行。
Service服务类型
Kubernetes 中Service有如下4中类型:
-
ClusterIP:默认类型,自动分配一个仅Cluster内部能够访问的虚拟IP
-
NodePort:经过每一个 Node 上的 IP 和静态端口(NodePort)暴露服务。以ClusterIP为基础,NodePort 服务会路由到 ClusterIP 服务。经过请求 <NodeIP>:<NodePort>,能够从集群的外部访问一个集群内部的 NodePort 服务。
-
LoadBalancer:使用云提供商的负载均衡器,能够向外部暴露服务。外部的负载均衡器能够路由到 NodePort 服务和 ClusterIP 服务。
-
ExternalName:经过返回 CNAME 和它的值,能够将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。没有任何类型代理被建立。
须要注意的是:Service 可以将一个接收 port 映射到任意的 targetPort。默认状况下,targetPort 将被设置为与 port 字段相同的值。
Service域名格式:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 为指定的集群的域名
主机名 | IP | OS |
---|---|---|
master | 192.168.58.110 | Centos |
node01 | 192.168.58.111 | Centos |
node02 | 192.168.58.125 | Centos |
ClusterIP:
默认类型,自动分配一个仅Cluster内部能够访问的虚拟IP
# 编写network.yaml资源清单文件
[root@master ~]# vi network.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
release: v1
template:
metadata:
labels:
app: myapp
release: v1
spec:
containers:
- name: myapp
image: xm17671855780/httpd:v1.0
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: myapp-nodeport
namespace: default
spec:
type: ClusterIP
selector:
app: myapp
release: v1
ports:
- name: httpd
port: 80
targetPort: 80
# 应用资源清单文件,创建资源
[root@master ~]# kubectl apply -f network.yaml
deployment.apps/myapp-deploy created
service/myapp-nodeport created
# 查看pod,service运行情况
[root@master ~]# kubectl get pods,svc
NAME READY STATUS RESTARTS AGE
pod/myapp-deploy-667bd747b6-6mkmq 1/1 Running 0 6m30s
pod/myapp-deploy-667bd747b6-wp65f 1/1 Running 0 6m30s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d22h
service/myapp-nodeport ClusterIP 10.98.209.123 <none> 80/TCP 6m30s
# 查看iptables,规则
[root@master ~]# iptables -t nat -nvL | grep 'myapp-nodeport'
0 0 KUBE-MARK-MASQ all -- * * 10.244.2.173 0.0.0.0/0 /* default/myapp-nodeport:httpd */
0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/myapp-nodeport:httpd */ tcp to:10.244.2.173:80
0 0 KUBE-MARK-MASQ all -- * * 10.244.1.126 0.0.0.0/0 /* default/myapp-nodeport:httpd */
2 120 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/myapp-nodeport:httpd */ tcp to:10.244.1.126:80
2 120 KUBE-SVC-UJB7KAYNZVW7NK6H tcp -- * * 0.0.0.0/0 10.98.209.123 /* default/myapp-nodeport:httpd cluster IP */ tcp dpt:80
2 120 KUBE-MARK-MASQ tcp -- * * !10.244.0.0/16 10.98.209.123 /* default/myapp-nodeport:httpd cluster IP */ tcp dpt:80
2 120 KUBE-SEP-WXLK2WHO6A3V7JDH all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/myapp-nodeport:httpd */ statistic mode random probability 0.50000000000
0 0 KUBE-SEP-BXPFXJRGQ62K7TWT all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/myapp-nodeport:httpd */
# 访问测试
[root@master ~]# curl 10.98.209.123
This is V1!
NodePort
nodePort的原理在于在node上开了一个端口,将向该端口的流量导入到kube-proxy,然后由 kube-proxy进一步到给对应的pod。若是将 type 字段设置为 NodePort,则 Kubernetes 控制层面将在 --service-node-port-range 标志指定的范围内分配端口(默认值:30000-32767)。
# 修改资源定义文件
[root@master ~]# vi network.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
release: v1
template:
metadata:
labels:
app: myapp
release: v1
spec:
containers:
- name: myapp
image: xm17671855780/httpd:v1.0
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: myapp-nodeport
namespace: default
spec:
type: NodePort // 指定NodePort类型
selector:
app: myapp
release: v1
ports:
- name: httpd
port: 80
targetPort: 80
nodePort: 30002 //指定对外端口
# 应用修改后的资源定义文件,重启pods
[root@master ~]# kubectl apply -f network.yaml
deployment.apps/myapp-deploy unchanged
service/myapp-nodeport configured
# 查看pods,service状态
[root@master ~]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/myapp-deploy-667bd747b6-6mkmq 1/1 Running 0 30m
pod/myapp-deploy-667bd747b6-wp65f 1/1 Running 0 30m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d23h
service/myapp-nodeport NodePort 10.98.209.123 <none> 80:30002/TCP 30m
# 查看iptables 规则
[root@master ~]# iptables -t nat -nvL | grep 'myapp-nodeport'
1 60 KUBE-SVC-UJB7KAYNZVW7NK6H tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/myapp-nodeport:httpd */ tcp dpt:30002
0 0 KUBE-MARK-MASQ all -- * * 10.244.2.173 0.0.0.0/0 /* default/myapp-nodeport:httpd */
0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/myapp-nodeport:httpd */ tcp to:10.244.2.173:80
0 0 KUBE-MARK-MASQ all -- * * 10.244.1.126 0.0.0.0/0 /* default/myapp-nodeport:httpd */
1 60 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/myapp-nodeport:httpd */ tcp to:10.244.1.126:80
0 0 KUBE-SVC-UJB7KAYNZVW7NK6H tcp -- * * 0.0.0.0/0 10.98.209.123 /* default/myapp-nodeport:httpd cluster IP */ tcp dpt:80
0 0 KUBE-MARK-MASQ tcp -- * * !10.244.0.0/16 10.98.209.123 /* default/myapp-nodeport:httpd cluster IP */ tcp dpt:80
1 60 KUBE-MARK-MASQ tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/myapp-nodeport:httpd */ tcp dpt:30002
1 60 KUBE-SEP-WXLK2WHO6A3V7JDH all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/myapp-nodeport:httpd */ statistic mode random probability 0.50000000000
0 0 KUBE-SEP-BXPFXJRGQ62K7TWT all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/myapp-nodeport:httpd */
# 访问测试
[root@master ~]# curl 192.168.58.110:30002
This is V1!
LoadBalancer
LoadBalancer 可以将来自客户端的请求分发到不同的服务器(阿里云、腾讯云、AWS),通过将一系列的请求转发到不同的服务器可以提高服务器的性能,并可以自动地寻找最优的服务器转发请求,这样不仅提高了系统性能,同时达到了负载均衡的目的,满足了用户需求,因此 LoadBalancer 在应用场景中一般处于 web 服务器的前端,用来均衡发到 web 服务器的请求量,均衡负载,提高系统性能。LoadBalancer 可以连接多个 web server,从而将多个 web server 组成一个集群(cluster),集群中负载的分配通过 loadBalancer 进行控制和管理。当然为了更好地进行负载均衡,LoadBalancer 也可以构建为一个集群,使用 LoadBalancer 构建的 web server cluster。
LoadBalancer示例,需要使用到相关云厂商服务支持,这里就不表述了。
ExternalName类型示例
这种类型的Service经过返回CNAME和它的值,能够将服务映射到externalName字段的内容(例如:my.k8s.example.com;能够实现跨namespace名称空间访问)。ExternalName Service是Service的特例,它没有selector,也没有定义任何的端口和Endpoint。相反的,对于运行在集群外部的服务,它经过返回该外部服务的别名这种方式提供服务。
# 修改netwoek.yanl资源定义文件
[root@master ~]# vi network.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
release: v1
template:
metadata:
labels:
app: myapp
release: v1
spec:
containers:
- name: httpd
image: xm17671855780/file_httpd:v0.2 //此处将镜像,更换为基于contos编译的httpd镜像
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: myapp-externalname
namespace: default
spec:
type: ExternalName //指定类型
externalName: my.k8s.example.com
# 使用修改过后的资源定义文件,重启pods
[root@master ~]# kubectl apply -f network.yaml
deployment.apps/myapp-deploy configured
service/myapp-externalname unchanged
# 查看pod,service状态
[root@master ~]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/myapp-deploy-6768948cc-4tp9j 1/1 Running 0 9m8s
pod/myapp-deploy-6768948cc-x5ncr 1/1 Running 0 9m6s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d
service/myapp-externalname ExternalName <none> my.k8s.example.com <none> 32m
# 此处Type,改为 ExternalName模式了
宿主机dig命令安装
# 进入pods中的某个容器中
[root@master ~]# kubectl exec -it myapp-deploy-6768948cc-4tp9j /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
sh-4.4# /bin/bash
[root@myapp-deploy-6768948cc-4tp9j src]# ls
apr-1.7.0 apr-util-1.6.1 debug httpd-2.4.48 kernels
[root@myapp-deploy-6768948cc-4tp9j src]# cd
[root@myapp-deploy-6768948cc-4tp9j ~]# yum install -y bind-utils // 安装包组
coredns记录信息如下
# 经过 nslookup 访问
[root@myapp-deploy-6768948cc-4tp9j ~]# nslookup myapp-externalname.default.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10#53
myapp-externalname.default.svc.cluster.local canonical name = my.k8s.example.com.
** server can't find my.k8s.example.com: NXDOMAIN
# 其中 10.96.0.10 为 coredns IP
# myapp-externalname.default.svc.cluster.local 为Service域名。格式为:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 指定的集群的域名
# 经过 dig 访问
[root@myapp-deploy-6768948cc-4tp9j ~]# dig -t A myapp-externalname.default.svc.cluster.local.@10.96.0.10
; <<>> DiG 9.11.26-RedHat-9.11.26-6.el8 <<>> -t A myapp-externalname.default.svc.cluster.local.@10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 24780
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 1293df4bb1831323 (echoed)
;; QUESTION SECTION:
;myapp-externalname.default.svc.cluster.local.\@10.96.0.10. IN A
;; Query time: 1012 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Sat Dec 25 04:08:21 UTC 2021
;; MSG SIZE rcvd: 97
ExternalIP示例
若是外部的 IP 路由到集群中一个或多个 Node 上,Kubernetes Service 会被暴露给这些 externalIPs。经过外部 IP(做为目的 IP 地址)进入到集群,打到 Service 端口上的流量,将会被路由到 Service 的 Endpoint 上。
externalIPs 不会被 Kubernetes 管理,它属于集群管理员的职责范畴。
根据 Service 的规定,externalIPs 能够同任意的 ServiceType 来一块儿指定。在下面的例子中,my-service 能够在【模拟外网IP】“10.0.0.240”(externalIP:port) 上被客户端访问。
# 编写 network.yaml资源定义文件
[root@master ~]# vi network.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
release: v1
template:
metadata:
labels:
app: myapp
release: v1
spec:
containers:
- name: httpd
image: xm17671855780/file_httpd:v0.2
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: myapp-externalip
namespace: default
spec:
selector:
app: myapp
release: v1
ports:
- name: httpd
port: 80
targetPort: 80
externalIPs:
- 10.0.0.240
# 应用资源定义文件,部署资源
[root@master ~]# kubectl apply -f network.yaml
deployment.apps/myapp-deploy unchanged
service/myapp-externalip created
# 查看pods,service状态
[root@master ~]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d3h <none>
myapp-externalip ClusterIP 10.99.109.176 10.0.0.240 80/TCP 13s app=myapp,release=v1
myapp-externalname ExternalName <none> my.k8s.example.com <none> 3h45m <none>
# curl访问,经过ClusterIP
[root@master ~]# curl 10.99.109.176
<html><body><h1>It works!</h1></body></html>
# curl访问,经过ExternalIP
[root@master ~]# curl 10.0.0.240
<html><body><h1>It works!</h1></body></html>
综合案例
创建一个deployment副本数为3,然后滚动更新镜像版本,并记录这个更新记录,最后再回滚到上一个版本
[root@master ~]# vi test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3 //副本数量
revisionHistoryLimit: 5 //版本留存数量
strategy:
rollingUpdate:
maxSurge: 50%
maxUnavailable: 50%
type: RollingUpdate
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: xm17671855780/httpd:v1.0
imagePullPolicy: IfNotPresent
[root@master ~]# kubectl apply -f test.yaml
deployment.apps/web created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-66dc445c66-99pn4 1/1 Running 0 6s
web-66dc445c66-rm8nk 1/1 Running 0 6s
web-66dc445c66-xzbwm 1/1 Running 0 6s
[root@master ~]# kubectl rollout history deployment/web //查看历史,历史版本被保留
deployment.apps/web
REVISION CHANGE-CAUSE
1 <none>
[root@master ~]# vi test.yaml
......
containers:
- name: httpd
image: xm17671855780/httpd:v2.0 //更改镜像
imagePullPolicy: IfNotPresent
......
[root@master ~]# kubectl apply -f test.yaml //应用部署,更新到版本2
deployment.apps/web configured
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-66dc445c66-99pn4 1/1 Terminating 0 3m9s
web-66dc445c66-rm8nk 1/1 Terminating 0 3m9s
web-66dc445c66-xzbwm 1/1 Terminating 0 3m9s
web-689dbd69c9-5szrd 1/1 Running 0 9s
web-689dbd69c9-pmgjc 1/1 Running 0 10s
web-689dbd69c9-zgn99 1/1 Running 0 10s
[root@master ~]# kubectl rollout history deployment/web //看到有两个版本
deployment.apps/web
REVISION CHANGE-CAUSE
1 <none>
2 <none>
# 回滚至版本1
[root@master ~]# kubectl rollout undo deployment/web --to-revision=1
deployment.apps/web rolled back
# 当前处于版本1,但是只使用了两个镜像,所以被覆盖,替换了。
[root@master ~]# kubectl rollout history deployment/web
deployment.apps/web
REVISION CHANGE-CAUSE
2 <none>
3 <none>
给一个应用扩容副本为4
[root@master ~]# kubectl scale --replicas 4 deployment/web
deployment.apps/web scaled
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-66dc445c66-lkxb5 1/1 Running 0 4m30s
web-66dc445c66-qgsjn 1/1 Running 0 4m30s
web-66dc445c66-sj7bw 1/1 Running 0 4m29s
web-66dc445c66-tfv6n 1/1 Running 0 2s
创建一个pod,其中运行着nginx、redis、memcached3个容器
# 编写hostwork.yaml资源定义文件
[root@master ~]# vi hostwork.yaml
apiVersion: v1
kind: Pod //定义pod类型
metadata:
name: test //定义pod名
labels:
app: who-are-you //打标签
spec:
containers: //定义镜像
- image: nginx
name: nginx
- image: redis
name: redis
- image: memcached
name: memcached
# 应用资源定义文件,创建资源
[root@master ~]# kubectl apply -f hostwork.yaml
pod/test created
# 查看pod状态
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test 0/3 ContainerCreating 0 8s
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test 3/3 Running 0 2m32s
# 查看pod详细信息
[root@master ~]# kubectl describe pods test
Name: test
Namespace: default
Priority: 0
Node: node01/192.168.58.111
Start Time: Sun, 26 Dec 2021 09:25:26 +0800
Labels: app=who-are-you
Annotations: <none>
Status: Running
IP: 10.244.1.144
IPs:
IP: 10.244.1.144
Containers:
nginx:
Container ID: docker://f6c9ce6e38827bed062054821858762debc661da25f84bcab5dc9866534dff46
Image: nginx
Image ID: docker-pullable://nginx@sha256:18d4060f8c221c35cde8153e9cb05b225ea8e05ed750514e9271bbcc36c61bae
Port: <none>
Host Port: <none>
State: Running
Started: Sun, 26 Dec 2021 09:25:44 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7wm92 (ro)
redis:
Container ID: docker://1d5f6aa03233a1aefd2dd2eda2d86cbf8618395764380aeaf56a34accf2be534
Image: redis
Image ID: docker-pullable://redis@sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339
Port: <none>
Host Port: <none>
State: Running
Started: Sun, 26 Dec 2021 09:26:00 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7wm92 (ro)
memcached:
Container ID: docker://036568cf2275901d2808f666fe6eb6a507df45c47b675a59b925d011f1dcf288
Image: memcached
Image ID: docker-pullable://memcached@sha256:a7895a53299404c294de9d8b0627c2585e924c389783f77c30df0cf6a316750c
Port: <none>
Host Port: <none>
State: Running
Started: Sun, 26 Dec 2021 09:26:16 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7wm92 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-7wm92:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m40s default-scheduler Successfully assigned default/test to node01
Normal Pulling 2m39s kubelet Pulling image "nginx"
Normal Pulled 2m23s kubelet Successfully pulled image "nginx" in 15.889668022s
Normal Created 2m23s kubelet Created container nginx
Normal Started 2m22s kubelet Started container nginx
Normal Pulling 2m22s kubelet Pulling image "redis"
Normal Created 2m7s kubelet Created container redis
Normal Pulled 2m7s kubelet Successfully pulled image "redis" in 15.557081559s
Normal Started 2m6s kubelet Started container redis
Normal Pulling 2m6s kubelet Pulling image "memcached"
Normal Pulled 111s kubelet Successfully pulled image "memcached" in 15.555695122s
Normal Created 111s kubelet Created container memcached
Normal Started 110s kubelet Started container memcached
给一个pod创建service,并可以通过ClusterIP/NodePort
# 编写hostwork.yaml资源定义文件
[root@master ~]# vi hostwork.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: myapp
release: v1
template:
metadata:
labels:
app: myapp
release: v1
spec:
containers:
- name: myapp
image: xm17671855780/file_httpd:v0.2
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: myapp-nodeport
namespace: default
spec:
type: NodePort
selector:
app: myapp
release: v1
ports:
- name: httpd
port: 80
targetPort: 80
nodePort: 31960
# 指定资源定义文件,部署资源
[root@master ~]# kubectl apply -f hostwork.yaml
deployment.apps/myapp-deploy created
service/myapp-nodeport created
# 查看pods,service状态
[root@master ~]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/myapp-deploy-79b6dccb8-h7mlh 1/1 Running 0 12s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d4h
service/myapp-externalname ExternalName <none> my.k8s.example.com <none> 4h26m
service/myapp-nodeport NodePort 10.99.153.177 <none> 80:31960/TCP 12s
# 使用CLUSTER-IP访问
[root@master ~]# curl 10.99.153.177
<html><body><h1>It works!</h1></body></html>
# 使用NodePort访问
[root@master ~]# curl 192.168.58.110:31960
<html><body><h1>It works!</h1></body></html>
创建deployment和service,使用centos容器Nslookup解析service
# 创建一个pod,service
[root@master ~]# vi hostwork.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: myapp
release: v1
template:
metadata:
labels:
app: myapp
release: v1
spec:
containers:
- name: myapp
image: xm17671855780/file_httpd:v0.2
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: myapp-externalname
namespace: default
spec:
type: ExternalName
externalName: web.test.example.com
# 查看现有资源
[root@master ~]# kubectl get pods(无)
No resources found in default namespace.
# 部署
[root@master ~]# kubectl apply -f hostwork.yaml
deployment.apps/myapp-deploy created
# 查看pods,service状态
[root@master ~]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/myapp-deploy-79b6dccb8-95ckd 1/1 Running 0 3m19s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d4h
service/myapp-externalname ExternalName <none> web.test.example.com <none> 4h45m
# 辨析一个busybox资源定义文件
[root@master ~]# vibusybox.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: busybox-pod
name: test-busybox
spec:
containers:
- command:
- sleep
- "3600"
image: busybox
imagePullPolicy: Always
name: test-busybox
# 部署
[root@master ~]# kubectl apply -f busybox.yaml
pod/test-busybox created
# 查看pods,svc的状态
[root@master ~]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/myapp-deploy-79b6dccb8-95ckd 1/1 Running 1 (2m30s ago) 3h37m
pod/test 3/3 Running 3 (3m31s ago) 4h12m
pod/test-busybox 0/1 ContainerCreating 0 9s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d1h
service/myapp-externalname ExternalName <none> web.test.example.com <none> 25h
service/myapp-nodeport NodePort 10.97.233.242 <none> 80:31960/TCP 3h46m
# 使用exec -it对test-busybox进行交互
[root@master ~]# kubectl exec -it test-busybox /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # nslookup myapp-externalname.default.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10:53
myapp-externalname.default.svc.cluster.local canonical name = web.test.example.com
*** Can't find myapp-externalname.default.svc.cluster.local: No answer
# myapp-externalname.default.svc.cluster.local 为Service域名。格式为:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 指定的集群的域名