k3s,k8s集群hello world部署
节点node
节点: 安装有k3s,k8s环境的主机或虚拟机,分为control-plane,master
主控节点和<none>
一般节点。每个节点已安装好容器环境(Docker等), 并且最好安装上需要image镜像, 这样可避免远程拉去image。 给每个node设置好label标签, 可方便后期规划任务的分配。
节点添加标签`sudo kubectl label node <node-name> <label-key>=<label-value>`。
节点删除标签`sudo kubectl label node <node-name> <label-key>-`, 减号表示删除。
查询节点的标签`sudo kubectl get node --show-labels`。
编排单位
- pod 最小的编排单位,由一个或多个容器组成。一个pod不会跨越多个节点,所有pod内的容器共享相同的ip和端口空间。缺点:不能设置并发数量,只能创建一个实例。
- Deployment 可以通过scale来进行弹性扩容,做负载均衡。
- Service 专用做服务器对外暴露设定,指定 Deployment 或者特定集合 Pod 的网络层抽象。
YAML 描述文件
编排单位的设定用命令也可以设定,但是不方便,k8s支持yaml进行描述。
参考Kubernetes之yaml文件详解
Pod 示例
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Deployment 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Service 示例
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
部署deployment.yaml 和 server.yaml
sudo kubectl apply -f deployment.yaml
sudo kubectl apply -f server.yaml
查看状态
sudo kubectl get pods
sudo kubectl get services
删除
sudo kubectl delete -f xxx.yaml
强制删除Terminating中的pod
sudo kubectl delete pod POD_NAME --force --grace-period=0
网络
参考:k8s中的网络
k8s组网要求
- 所有的Pods之间可以在不使用NAT网络地址转换的情况下相互通信
- 所有的Nodes之间可以在不使用NAT网络地址转换的情况下相互通信
- 每个Pod自己看到的自己的ip和其他Pod看到的一致
k8s网络模型设计原则
- 每个Pod都拥有一个独立的 IP地址,而且 假定所有 Pod 都在一个可以直接连通的、扁平的网络空间中 。
- 不管它们是否运行在同 一 个 Node (宿主机)中,都要求它们可以直接通过对方的 IP 进行访问。
- 设计这个原则的原因 是,用户不需要额外考虑如何建立 Pod 之间的连接,也不需要考虑将容器端口映射到主机端口等问题。
访问服务的几种方式
- ClusterIP, service默认的地址类型,只能在集群内部访问.
- NodePort, service的端口暴露到node机器的对应端口,这就可以通关暴露的node从外部来访问集群服务。
- Service LoadBalancer, 云厂商的扩展接口。
- Ingress Controller。
前面的示例中使用了NodePort方式, 先展示一下集群节点情况:
$sudo kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ubuntu18 Ready,SchedulingDisabled control-plane,master 14d v1.21.5+k3s2 192.168.0.7 <none> Ubuntu 18.04.6 LTS 4.15.0-161-generic docker://20.10.9
u18node Ready <none> 14d v1.21.5+k3s2 192.168.0.13 <none> Ubuntu 18.04.6 LTS 4.15.0-161-generic docker://20.10.9
有两个节点, NodeIP地址分别是192.168.0.7
和192.168.0.13
。
在看下pod和service的运行情况:
$ sudo kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-7848d4b86f-g94qj 1/1 Running 2 14d 10.42.1.13 u18node <none> <none>
nginx-deployment-7848d4b86f-hc5k2 1/1 Running 2 14d 10.42.1.14 u18node <none> <none>
nginx-deployment-7848d4b86f-z2cm2 1/1 Running 2 14d 10.42.1.15 u18node <none> <none>
$ sudo kubectl get services -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 14d <none>
nginx-service NodePort 10.43.3.67 <none> 80:30080/TCP 22m app=nginx
nginx-deployment
有三个实例在运行, ClusterIP地址分别是:10.42.1.13, 10.42.1.14, 10.42.1.15
。nginx-service
的ClusterIP是10.43.3.67
, 暴露给集群内部的端口是80, 节点暴露的端口是30080.
现在有三台机器,ip地址分别是192.168.0.7
,192.168.0.13
和192.168.0.14
.
其中192.168.0.7
,192.168.0.13
已组集群,三台机器可以互通。
在集群内部的机器上直接访问pod服务端口。
curl 10.42.1.13:80 curl 10.42.1.14:80 curl 10.42.1.15:80
ip为
192.168.0.14
的机器不能通过这样的方式访问。不推荐这种访问方式,pod的分配是变化的,仅用作测试用。在集群内部的机器上访问service的服务端口。
curl 10.43.3.67:80
依然是只有
192.168.0.7
和192.168.0.13
可以访问,但是由于service的ClusterIP已经固定,所以可以用来做集群内部服务器暴露方法。在集群外的机器上访问node上暴露的端口。
curl 192.168.0.7:30080 curl 192.168.0.13:30080
这样就可以在
192.168.0.14
这台机器上访问nginx服务了。
NodePort方式,需要一台独立的node机器专门对外暴露访问,并做好端口映射和转发,就可以实现internet访问集群内部的服务了。