K8S简记

Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署,规划,更新,维护的一种机制。

目录

  • 概念
  • 组织结构
  • 安装
  • 常用命令
  • K8S配置文件编写

概念

Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。

Kubernetes 提供如下服务

  • 服务发现和负载均衡
  • 存储编排
  • 自动部署和回滚
  • 自动完成装箱计算
  • 自我修复
  • 密钥与配置管理

这张图表展示了包含所有相互关联组件的 Kubernetes 集群。

Kubernetes 组件

控制平面组件

控制平面的组件对集群做出全局决策(比如调度),以及检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod)。

  • kube-apiserver
  • etcd
  • kube-scheduler
  • kube-controller-manager
    • 节点控制器
    • 任务控制器
    • 端点控制器
    • 服务帐户和令牌控制器
  • cloud-controller-manager
    • 节点控制器
    • 路由控制器
    • 服务控制器

Node 组件

节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行环境。

插件

插件使用 Kubernetes 资源(DaemonSetDeployment等)实现集群功能。 因为这些插件提供集群级别的功能,插件中命名空间域的资源属于 kube-system 命名空间。

  • DNS
  • Web 界面 Dashboard
  • 容器资源监控
  • 集群层面日志

Kubernetes 对象

Kubernetes 使用Kubernetes 对象实体去表示整个集群的状态。

  • 哪些容器化应用在运行(以及在哪些节点上)
  • 可以被应用使用的资源
  • 关于应用运行时表现的策略,比如重启策略、升级策略,以及容错策略

操作 Kubernetes 对象 —— 无论是创建、修改,或者删除 —— 需要使用 Kubernetes API

对象 spec(规约) 和 对象 status(状态)

  • 对于具有 spec 的对象,你必须在创建对象时设置其内容,描述你希望对象所具有的特征: 期望状态(Desired State)

  • status 描述了对象的 当前状态(Current State),它是由 Kubernetes 系统和组件 设置并更新的。

当使用 Kubernetes API 创建对象时(或者直接创建,或者基于kubectl), API 请求必须在请求体中包含 JSON 格式的信息。 大多数情况下,需要在 .yaml 文件中为 kubectl 提供这些信息kubectl 在发起 API 请求时,将这些信息转换成 JSON 格式。

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

在想要创建的 Kubernetes 对象对应的 .yaml 文件中,需要配置如下的字段:

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
  • kind - 想要创建的对象的类别
  • metadata - 帮助唯一性标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace
  • spec - 你所期望的该对象的状态

组织结构

K8S : 节点(容器)的集合

node:K8S的工作机器

Pod:表示集群上正在运行的一组容器

ReplicaSet:容器的副本

Deployment:用于部署应用的对象

container:容器(docker)

service:将pods上的应用的网络映射出去的抽象方法

Pod创建流程:

安装

1.0 常用命令

1
2
3
4
5
6
7
8
9
10
apt download tree
apt download libonig5 libjq1 jq
apt download socat
apt downlaod conntrack
dpkg -i tree_1.8.0-1_amd64.deb
dpkg -i libonig5_6.9.4-1_amd64.deb
dpkg -i libjq1_1.6-1ubuntu0.20.04.1_amd64.deb
dpkg -i jq_1.6-1ubuntu0.20.04.1_amd64.deb
dpkg -i socat_1.7.3.3-2_amd64.deb
dpkg -i conntrack_1.3a1.4.5-2_amd64.deb

1.1 Docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apt-get purge docker-ce docker-ce-cli containerd.io -y
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
sudo apt-get remove docker docker-engine docker.io containerd runc -y

wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/containerd.io_1.4.12-1_amd64.deb
wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/docker-ce-cli_19.03.15~3-0~ubuntu-focal_amd64.deb
wget https://download.docker.com/linux/ubuntu/dists/focal/pool/stable/amd64/docker-ce_19.03.15~3-0~ubuntu-focal_amd64.deb
dpkg -i containerd.io_1.4.12-1_amd64.deb
dpkg -i docker-ce-cli_19.03.15~3-0~ubuntu-focal_amd64.deb
dpkg -i docker-ce_19.03.15~3-0~ubuntu-focal_amd64.deb
apt-mark hold containerd.io
apt-mark hold docker-ce-cli
apt-mark hold docker-ce

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o docker-compose
sudo chmod +x docker-compose
cp docker-compose /usr/local/bin

参考

Install Docker Compose | Docker Documentation

Install Docker Engine on Ubuntu | Docker Documentation

Index of linux/ubuntu/dists/ (docker.com)

1.2 Kubernetes

允许 iptables 检查桥接流量

1
2
3
4
5
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

安装 cni 命令

1
2
3
4
CNI_VERSION="v0.8.2"
wget "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz"
sudo mkdir -p /opt/cni/bin
sudo tar -f cni-plugins-linux-amd64-${CNI_VERSION}.tgz -C /opt/cni/bin -xz

安装 crictl 命令

1
2
3
CRICTL_VERSION="v1.19.0"
wget "https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-amd64.tar.gz"
sudo tar -f crictl-${CRICTL_VERSION}-linux-amd64.tar.gz -C /usr/local/bin -xz

安装 kube 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
DOWNLOAD_DIR="/usr/local/bin"
RELEASE_VERSION="v1.19.16"
sudo curl -L --remote-name-all https://dl.k8s.io/${RELEASE_VERSION}/bin/linux/amd64/{kubeadm,kubelet,kubectl}
sudo chmod +x {kubeadm,kubelet,kubectl}
cp {kubeadm,kubelet,kubectl} $DOWNLOAD_DIR

RELEASE_VERSION="v0.4.0"
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee kubelet.service
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee 10-kubeadm.conf

sudo mkdir -p /etc/systemd/system/kubelet.service.d
cp kubelet.service /etc/systemd/system/
cp 10-kubeadm.conf /etc/systemd/system/kubelet.service.d/

systemctl enable --now kubelet
systemctl daemon-reload
systemctl restart kubelet

配置 docker 驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mkdir /etc/docker
cat > daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": [
"https://registry.docker-cn.com",
"https://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com",
"https://cr.console.aliyun.com/"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "256m"
},
"storage-driver": "overlay2"
}
EOF

cp daemon.json /etc/docker/
sudo systemctl daemon-reload
service docker restart
service docker status

参考:

Download Kubernetes

Install and Set Up kubectl on Linux | Kubernetes

Installing kubeadm | Kubernetes

Install Tools | Kubernetes

2. 集群搭建

2.1 网络配置

开始安装前确保每台机器的主机名、网卡MAC地址都是唯一的。

依次配置静态IP地址192.168.200.128、192.168.200.129、192.168.200.130。

VMware的虚拟机如果要让其他机器访问,要先把虚拟机设置为桥接模式(不需要复制物理网络连接状态),然后把IP迁移到所桥接的网卡的网段下面。最好到网络适配器里面充值一下MAC地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
# /etc/netplan/00-installer-config.yaml
network:
ethernets:
ens32:
addresses:
- 192.168.200.130/24
gateway4: 192.168.200.2
nameservers:
addresses:
- 223.5.5.5
- 223.6.6.6
search: []
version: 2

Master节点开放如下端口:

  • 6443 kubernetes api server
  • 2379-2380 etcd server client api
  • 10250 kubelet api
  • 10251 kube-scheduler
  • 10252 kube-controller-manager
  • 10255 read-only kubelet api (heapster)
1
2
3
4
5
6
7
ufw allow 6443
ufw allow 2379
ufw allow 2380
ufw allow 10250
ufw allow 10251
ufw allow 10252
ufw allow 10255

Worker节点

  • 10250 kubelet api
  • 10255 read-only kubelet api (heapster)
  • 30000-32767 default port range for NodePort Services
1
2
3
4
ufw allow 10250
ufw allow 10255
ufw allow 30000:32767/tcp
ufw allow 30000:32767/udp

其他防火墙规则自行定义。

2.2 启动节点

启动 Master

1
2
3
4
5
6
7
8
hostnamectl set-hostname kubemaster
# 如果要使用其他pod-network-cidr需要同时修改calico.yaml。
kubeadm init --pod-network-cidr 192.168.0.0/16 --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers --kubernetes-version v1.19.16 --v=6

rm -rf $HOME/.kube
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

启动 Worker1

1
2
hostnamectl set-hostname kubeworker1
kubeadm join 192.168.200.128:6443 --token cv46y9.itvzhbzn0wyyx5k1 --discovery-token-ca-cert-hash sha256:4eba29149c287ef57c01bf8310cb5d202afd88906e67665352ad2919f0b4ad6b

启动 Worker2

1
2
hostnamectl set-hostname kubeworker2
kubeadm join 192.168.200.128:6443 --token cv46y9.itvzhbzn0wyyx5k1 --discovery-token-ca-cert-hash sha256:4eba29149c287ef57c01bf8310cb5d202afd88906e67665352ad2919f0b4ad6b

如果之后有新的节点需要加入网络,则需要在Master上执行如下命令

1
2
3
4
5
kubeadm token create
# 例如得到pxyrmw.g19twnwtchqtvr58
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
# 例如得到9210114b1234d10a38837c7f2ee95d9c1cc875caa504aba6f2d3509ffdcc3066
kubeadm join 172.18.118.194:6443 --token pxyrmw.g19twnwtchqtvr58 --discovery-token-ca-cert-hash sha256:9210114b1234d10a38837c7f2ee95d9c1cc875caa504aba6f2d3509ffdcc3066 -v=6

安装网络插件

1
2
3
wget https://docs.projectcalico.org/manifests/calico.yaml
kubectl apply -f calico.yaml
kubectl get pods -o wide -n kube-system

设置节点角色

1
2
3
4
5
# 为节点添加角色
kubectl label nodes kubeworker1 node-role.kubernetes.io/node=
kubectl label nodes kubeworker2 node-role.kubernetes.io/node=
# 允许Master调度容器
kubectl taint nodes --all node-role.kubernetes.io/master-

备份 docker 镜像

1
2
3
4
5
6
7
8
9
10
11
docker save -o calico-node-v3.21.1.tar calico/node:v3.21.1
docker save -o calico-pod2daemon-flexvol-v3.21.1.tar calico/pod2daemon-flexvol:v3.21.1
docker save -o calico-cni-v3.21.1.tar calico/cni:v3.21.1
docker save -o calico-kube-controllers-v3.21.1.tar calico/kube-controllers:v3.21.1
docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-kube-apiserver-v1.19.16.tar registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.19.16
docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-kube-controller-manager-v1.19.16.tar registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.19.16
docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-kube-proxy-v1.19.16.tar registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.19.16
docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-kube-scheduler-v1.19.16.tar registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.19.16
docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-etcd-3.4.13-0.tar registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.13-0
docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-coredns-1.7.0.tar registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.7.0
docker save -o registry.cn-hangzhou.aliyuncs.com-google_containers-pause-3.2.tar registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2

移除节点命令

1
kubectl drain ideacentre-geekpro-15ick --delete-local-data --force --ignore-daemonsets

2.3 高可用集群

kubeadm实现高可用的思路是先搭建负载均衡服务,在使用kubeadm init的时候增加选项—control-plane-endpoint—upload-certs即可。--control-plane-endpoint 标志应该被设置成负载均衡器的地址或 DNS 和端口;--upload-certs 标志用来将在所有控制平面实例之间的共享证书上传到集群。

然后节点使用kubeadm join加入集群的时候通过增加两个额外的选项—control-plane—certificate-key即可。—certificate-key的值在kubeadm init的时候会默认输出一个。过期之后也可用类似于token通过sudo kubeadm init phase upload-certs —upload-certs重新生成。

参考:

Cluster Networking | Kubernetes

Installing Addons | Kubernetes

Install Calico networking and network policy for on-premises deployments (tigera.io)

使用 Kops 安装 Kubernetes | Kubernetes

使用 Kubespray 安装 Kubernetes | Kubernetes

利用 kubeadm 创建高可用集群 | Kubernetes

3. 可视化界面

3.1 部署容器

1
2
3
4
5
6
7
8
wget -O dashboard.yaml https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml

# 备份镜像
docker save -o kubernetesui-dashboard-v2.2.0.tar kubernetesui/dashboard:v2.2.0
docker save -o kubernetesui-metrics-scraper-v1.0.6.tar kubernetesui/metrics-scraper:v1.0.6

# 通过标签指定哪些机器允许运行该服务
kubectl label node kubemaster dashboard-allowed=true

可以修改配置文件dashboard.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 30000
selector:
k8s-app: kubernetes-dashboard

kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
nodeSelector:
"kubernetes.io/hostname": "kubemaster"
"dashboard-allowed": "true"

# 通过设置NodePort来对外开放服务
# 所有容器定义都将imagePullPolicy设置为Never以防止重复拉取镜像(如果机器没联网)
# 容器可通过标签来选择指定节点进行部署

执行以下命令将Kubernetes Dashboard部署到集群中

1
2
3
4
5
6
7
8
9
10
11
12
13
kubectl apply -f dashboard.yaml
# 创建账户并查看token,忘记token也可以用最后一个命令再次查询
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

# 查看运行信息
kubectl get deployment --namespace=kubernetes-dashboard kubernetes-dashboard
kubectl describe deployment --namespace=kubernetes-dashboard kubernetes-dashboard
kubectl get service --namespace=kubernetes-dashboard kubernetes-dashboard
kubectl --namespace=kubernetes-dashboard get pod -o wide | grep dashboard
kubectl describe pod --namespace=kubernetes-dashboard
kubectl get pod --all-namespaces

常用命令

k8s对象管理

创建配置文件中定义的对象:

1
kubectl create -f nginx.yaml

删除两个配置文件中定义的对象:

1
kubectl delete -f nginx.yaml -f redis.yaml

通过覆盖活动配置来更新配置文件中定义的对象:

1
kubectl replace -f nginx.yaml

命名空间

将同一任务的虚拟集群称为命名空间。

Kubernetes 会创建四个初始名字空间:

  • default 没有指明使用其它名字空间的对象所使用的默认名字空间
  • kube-system Kubernetes 系统创建对象所使用的名字空间
  • kube-public 这个名字空间是自动创建的,所有用户(包括未经过身份验证的用户)都可以读取它。 这个名字空间主要用于集群使用,以防某些资源在整个集群中应该是可见和可读的。 这个名字空间的公共方面只是一种约定,而不是要求。

你可以使用以下命令列出集群中现存的名字空间:

1
kubectl get namespace

为当前请求设置名字空间,请使用 --namespace 参数。

1
2
kubectl run nginx --image=nginx --namespace=<名字空间名称>
kubectl get pods --namespace=<名字空间名称>

删除命名空间。下面的命令会删除你根据这个任务创建的所有 Pod:

1
kubectl delete namespace mem-example

节点

你可以使用 kubectl 来查看节点状态和其他细节信息:

1
kubectl describe node <节点名称>

Pod

创建 Pod:

1
kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit-3.yaml --namespace=mem-example

查看 Pod 状态:

1
kubectl get pod memory-demo-3 --namespace=mem-example

查看关于 Pod 的详细信息,包括事件:

1
kubectl describe pod memory-demo-3 --namespace=mem-example

删除 Pod:

1
kubectl delete pod memory-demo-3 --namespace=mem-example

K8S配置文件编写

基础服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
apiVersion: v1             #指定api版本,此值必须在kubectl apiversion中  
kind: Pod #指定创建资源的角色/类型
metadata: #资源的元数据/属性
name: django-pod #资源的名字,在同一个namespace中必须唯一
labels: #设定资源的标签,使这个标签在service网络中备案,以便被获知
k8s-app: django
version: v1
kubernetes.io/cluster-service: "true"
annotations: #设置自定义注解列表
- name: String #设置自定义注解名字
spec: #设置该资源的内容
restartPolicy: Always #表示自动重启,一直都会有这个容器运行
nodeSelector: #选择node节点14 zone: node1
containers:
- name: django-pod #容器的名字
image: django:v1.1 #容器使用的镜像地址
imagePullPolicy: Never #三个选择Always、Never、IfNotPresent,每次启动时检查和更新(从registery)images的策略,
# Always,每次都检查
# Never,每次都不检查(不管本地是否有)
# IfNotPresent,如果本地有就不检查,如果没有就拉取
command: ['sh'] #启动容器的运行命令,将覆盖容器中的Entrypoint,对应Dockefile中的ENTRYPOINT
args: ["$(str)"] #启动容器的命令参数,对应Dockerfile中CMD参数
env: #指定容器中的环境变量
- name: str #变量的名字
value: "/etc/run.sh" #变量的值
resources: #资源管理
requests: #容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
cpu: 0.1 #CPU资源(核数),两种方式,浮点数或者是整数+m,0.1=100m,最少值为0.001核(1m)
memory: 32Mi #内存使用量
limits: #资源限制
cpu: 0.5
memory: 32Mi
ports:
- containerPort: 8080 #容器开发对外的端口
name: uwsgi #名称
protocol: TCP
livenessProbe: #pod内容器健康检查的设置
httpGet: #通过httpget检查健康,返回200-399之间,则认为容器正常
path: / #URI地址
port: 8080
#host: 127.0.0.1 #主机地址
scheme: HTTP
initialDelaySeconds: 180 #表明第一次检测在容器启动后多长时间后开始
timeoutSeconds: 5 #检测的超时时间
periodSeconds: 15 #检查间隔时间
#也可以用这种方法
#exec: 执行命令的方法进行监测,如果其退出码不为0,则认为容器正常
# command:
# - cat
# - /tmp/health
#也可以用这种方法
#tcpSocket: //通过tcpSocket检查健康
# port: number
lifecycle: #生命周期管理(钩子)
postStart: #容器运行之前运行的任务
exec:
command:
- 'sh'
- 'yum upgrade -y'
preStop: #容器关闭之前运行的任务
exec:
command: ['service httpd stop']
volumeMounts: #挂载设置
- name: volume #挂载设备的名字,与volumes[*].name 需要对应
mountPath: /data #挂载到容器的某个路径下
readOnly: True
volumes: #定义一组挂载设备
- name: volume #定义一个挂载设备的名字
#meptyDir: {}
hostPath:
path: /opt #挂载设备类型为hostPath,路径为宿主机下的/opt

kind的集中类型:

  • Pod:
  • Deployment : 主要用于部署pod,支持滚动升级。(Pod与Deployment类似,推荐使用Deployment)
  • Service:服务定义,主要用于暴露pods容器中的服务。
  • ConfigMap:主要用于容器配置管理。
  • Ingress:http路由规则定义,主要用于将service暴露到外网中。
  • CronJob :负责定时任务,在指定的时间周期运行指定的任务。
  • Job:用于批量处理短暂的一次性任务,并保证指定数量的Pod成功结束。

Service服务

  1. Kubernetes Service 从逻辑上代表了一组 Pod,具体是哪些 Pod 则是由 label 来挑选。

  2. Service 有自己 IP,而且这个 IP 是不变的。

    • 客户端只需要访问 Service 的 IP,Kubernetes 则负责建立和维护 Service 与 Pod 的映射关系。

    • 无论后端 Pod 如何变化,对客户端不会有任何影响,因为 Service 没有变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1 # 版本
kind: Service # 类型
metadata: # 元数据
name: # 资源名称
namespace: # 命名空间
spec:
selector: # 标签选择器,用于确定当前Service代理那些Pod
app: nginx
type: # Service的类型,指定Service的访问方式
clusterIP: # 虚拟服务的IP地址
sessionAffinity: # session亲和性,支持ClientIP、None两个选项,默认值为None
ports: # 端口信息
- port: 8080 # Service端口
protocol: TCP # 协议
targetPort : # Pod端口
nodePort: # 主机端口
  • ClusterIP:默认类型,处于该模式下K8S会自动为service分配地址,其只能在集群内部访问。
  • NodePort:将Service通过指定的Node上的端口暴露给外部,通过此方法,就可以在集群外部访问服务。
  • LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境的支持。
  • ExternalName:把集群外部的服务引入集群内部,直接使用。

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apiVersion: /v1
kind: Deployment
metadata:
name: httpd
spec:
selector:
matchLabels:
run: httpd
replicas: 3
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: httpd
ports:
- containerPort: 80
---
apiVersion: v1 # v1是service的apiversion
kind: Service # 当前资源的类型为 Service。
metadata:
name: httpd-svc # Service 的名字为 httpd-svc。
spec:
selector: # elector 指明挑选那些 label 为 run: httpd 的 Pod 作为 Service 的后端。
run: httpd
ports: # 将 Service 的 8080 端口映射到 Pod 的 80 端口,使用 TCP 协议。
- protocol: TCP
port: 8080
targetPort: 80

参考:
官方文档

service详解