AWS-EKS-13--Kubectl

摘要

kubectl命令

  • Kubernetes 提供 kubectl 是使用 Kubernetes API 与 Kubernetes 集群的控制面进行通信的命令行工具。

  • 官网文档

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
$ kubectl help
kubectl controls the Kubernetes cluster manager.

Find more information at: https://kubernetes.io/docs/reference/kubectl/

Basic Commands (Beginner):
create Create a resource from a file or from stdin
expose Take a replication controller, service, deployment or pod and
expose it as a new Kubernetes service
run 在集群上运行特定镜像
set 为对象设置指定特性

Basic Commands (Intermediate):
explain Get documentation for a resource
get 显示一个或多个资源
edit 编辑服务器上的资源
delete Delete resources by file names, stdin, resources and names, or
by resources and label selector

Deploy Commands:
rollout Manage the rollout of a resource
scale Set a new size for a deployment, replica set, or replication
controller
autoscale Auto-scale a deployment, replica set, stateful set, or
replication controller

Cluster Management Commands:
certificate 修改证书资源。
cluster-info Display cluster information
top Display resource (CPU/memory) usage
cordon 标记节点为不可调度
uncordon 标记节点为可调度
drain 清空节点以准备维护
taint 更新一个或者多个节点上的污点

Troubleshooting and Debugging Commands:
describe 显示特定资源或资源组的详细信息
logs 打印 Pod 中容器的日志
attach 挂接到一个运行中的容器
exec 在某个容器中执行一个命令
port-forward 将一个或多个本地端口转发到某个 Pod
proxy 运行一个指向 Kubernetes API 服务器的代理
cp Copy files and directories to and from containers
auth Inspect authorization
debug Create debugging sessions for troubleshooting workloads and nodes
events List events

Advanced Commands:
diff Diff the live version against a would-be applied version
apply Apply a configuration to a resource by file name or stdin
patch Update fields of a resource
replace Replace a resource by file name or stdin
wait Experimental: Wait for a specific condition on one or many
resources
kustomize Build a kustomization target from a directory or URL.

Settings Commands:
label 更新某资源上的标签
annotate 更新一个资源的注解
completion Output shell completion code for the specified shell (bash, zsh, fish, or powershell)

Other Commands:
alpha Commands for features in alpha
api-resources Print the supported API resources on the server
api-versions Print the supported API versions on the server, in the form of "group/version"
config 修改 kubeconfig 文件
plugin Provides utilities for interacting with plugins
version 输出客户端和服务端的版本信息

context[集群]相关

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
# 查看client和server版本,注意此时必须连上server端
k version
k version --output=yaml/json

# 只查看client版本
k version --client --short
k version --client --output=yaml

# 查看所有资源信息,会显示name,shortname,版本,KIND等等
k api-resources

# 查看全部context配置,会显示所有context,当前context前面会用星号标识,同时显示其默认的namespace
k config get-contexts
# 查看当前context
k config current-context

# 切换到指定的context,后面跟上面命令查询出来的context的名称,同时修改k8s的配置文件,默认在~/.kube/config 文件
k config use-context eks-lexing
# 作用同上,都是切换上下文
k config set current-context ekstest

# 修改当前context的名称
k config rename-context $(k config current-context) ty-hk-eks

# 查看~/.kube/config 文件
k config view

# 列出所有插件文件路径
k plugin list

# 查看集群信息
k cluster-info

节点相关

1
2
3
4
# 查看当前集群下的node
k get nodes
# 显示更多信息,比如ip地址
k get nodes -o wide

namespace–ns相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 获取当前集群下所有namespace
k get namespaces
# namespace可以简写为ns
k get ns

# 查看当前默认的namespace
k config get-contexts $(k config current-context)

# 设置当前集群缺省的namespace,同时修改k8s的配置文件,默认在~/.kube/config 文件
k config set-context --current --namespace=default
k config set-context $(k config current-context) --namespace default

# 创建一个新的namespace
k create namespace hanqf
k create ns hanqf

# 不创建,只生成yaml文件
k create ns hanqf --dry-run=client -o yaml > namespace_hanqf.yaml
# 基于yaml创建namespace
k apply -f namespace_hanqf.yaml

# 删除namespace,删除的同时会删除namespace下的所有资源
k delete namespace hanqf

pod–po相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 获取当前namespace下的pod
k get pods
# 显示更多信息,比如ip地址
k get pods -o wide
# 列出标签
k get pods --show-labels

# 显示所有namespace下的pod
k get pods -A
# 显示指定namespace下的pod
k get pods -n jx-git-operator

# 创建pod
k run nginx --image=nginx:1.9 --port=80
# 生成yaml
k run nginx --image=nginx:1.9 --port=80 --dry-run=client -o yaml > nginx.yaml

# 查看pod创建后的配置信息,可以使用k apply -f nginx2.yaml重新创建pod
k get pods nginx --output=yaml > nginx2.yaml

# 执行yaml配置创建
k apply -f pod.yaml

controller相关


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 获取当前namespace下的deployment
k get deployments
# 查看指定的deployment的配置信息
k describe deployments test-nginx
# 编辑指定的deployment
k edit deployments test-nginx
# 删除指定的deployment
k delete deployments test-nginx

# 以下同上
# 获取当前namespace下的statefulset,job,cronjob,daemonset
k get statefulsets
k get jobs
k get cronjobs
k get daemonsets

deployment–deploy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myngx
spec:
replicas: 3
selector:
matchLabels:
app: myngx
template:
metadata:
labels:
app: myngx
spec:
containers:
- image: nginx:1.7.9
name: myngx
ports:
- containerPort: 80
resources:
requests:
cpu: 8m
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
# 命令行创建deploy
k create deployment test-nginx --image=nginx:1.9 --port=80 --replicas=2
# 创建yaml
k create deployment test-nginx --image=nginx:1.9 --port=80 --replicas=2 --dry-run=client -o yaml > deploy_new.yaml
# 创建delpoyment
k apply -f deploy_new.yaml

# 查看deploy对应的rs信息,会显示升级历史
k get rs -owide -l app=test-nginx

# 重新启动deploy
kubectl rollout restart deployment test-nginx


# 查看全部deployment
k get deploy
# 将指定的deployment输出到yaml
k get deploy myngx -o yaml > deploy_nginx.yaml
# 删除deployment
k delete deploy myngx
# 重新创建deployment
k apply -f deploy_nginx.yaml


# 扩缩容,pod不支持扩缩容,只有rs,deploy,sts等高级别controller才有扩缩容能力
k scale deploy myngx --replicas=4
# rs,deploy,sts等高级别controller都具有自愈能力,如果其下的pod被删除了,会自动重新创建新的pod

# 修改deploy
# 方式1:编辑配置,就是vim,保存后立即生效
k edit deploy test-nginx

# 方式2: 命令行,比如修改过镜像版本
# k set image deployment deploy名称 镜像名称=镜像
k set image deployment test-nginx nginx=nginx:1.7.9

# 查看升级是否成功
k rollout status -w deployment test-nginx

# 查看deploy对应的rs信息,会显示升级历史
k get rs -owide -l app=test-nginx
# 查看历史版本记录,每行前有个版本号
k rollout history deploy test-nginx
# 查看指定历史版本号的详细信息
k rollout history deploy test-nginx --revision=2

# 回退到上一个版本
k rollout undo deploy test-nginx
# 回退到指定的版本
k rollout undo deploy test-nginx --to-revision=2

daemonset–ds

  • 每个node都会创建一个pod,当有新的node加入进来时,pod会自动被daemonset调度到新的node上,同理删除node,该node上的pod也会被移除

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
# ds1.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds1
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: mynginx
template:
metadata:
labels:
name: mynginx
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: mynginx
image: nginx:1.7.9
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
1
2
3
4
5
6
7
8
9
10
# 创建ds
k apply -f ds1.yaml
# daemonset不支持使用create创建,但其格式与deployment差不多,可以先通过create创建deploy的yaml,然后对其进行修改,
# 如修改 apiVersion 和 kind,同时还要去掉replicas,另外需要加上tolerance的配置,保证其在master节点上也能部署
k run nginx --image=nginx:1.9 --dry-run -o yaml > ds_new.yaml

# 查询ds
k get ds -n kube-system
# 删除
k delete ds -n kube-system ds1

job

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: job-demo
spec:
template:
metadata:
name: job-demo
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox
command:
- "bin/sh"
- "-c"
- "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"
imagePullPolicy: IfNotPresent
1
2
k apply -f job.yaml
k get jobs

cronjob–cj

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob-demo
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: hello
image: busybox
args:
- "bin/sh"
- "-c"
- "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"
1
2
3
k apply -f cronjob.yaml
k get cronjob -o wide
k get job

statefulset–sts

  • sts的特性
    ● 稳定的、唯一的网络标识。
    ● 稳定的、持久化的存储。
    ● 有序的、优雅的部署和扩展。
    ● 有序的、优雅的删除和停止。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# sts.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.9
ports:
- containerPort: 80
name: web
1
2
k apply -f sts.yaml
k get sts -owide

label标签

  • controller和service等都是基于标签选择器关联pod的,所以在指定label时一定要准确唯一

1
2
3
4
5
6
7
8
9
# 可以为任何资源设置标签
# k label 资源类型 资源名称 key=value
k label deploy myngx app=test
# 查看标签
k get deploy --show-labels
# 查看指定的标签值,标签会占用一列进行展示,多个标签使用逗号分隔,如果资源不存在该标签,则为空
k get pod -L app,run
# 只列出给定标签和值的资源
k get pod -l app=test

Configmap–cm

  • 用来存储配置文件的 kubernetes 资源对象,配置内容都存储在 etcd 中

  • 创建方法

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# 通过直接在命令行中指定 configmap 参数创建,即--from-literal
$ k create configmap config-map1 --from-literal=db.host=mysql.db --from-literal=db.port='3306'
$ k describe cm config-map1
Name: config-map1
Namespace: test
Labels: <none>
Annotations: <none>

Data
====
db.host:
----
mysql.db
db.port:
----
3306

BinaryData
====

Events: <none>

# 通过指定文件创建,即将一个配置文件创建为一个 ConfigMap --from-file=<文件>
# 如果不指定key,则文件名称作为key
$ vi configs/app.properties
db.host mysql.db
db.port 3306

$ k create configmap config-map2 --from-file=key1=./configs/app.properties
$ k describe cm config-map2
Name: config-map2
Namespace: test
Labels: <none>
Annotations: <none>

Data
====
key1:
----
db.host mysql.db
db.port 3306


BinaryData
====

Events: <none>

# 通过指定目录创建,即将一个目录下的所有配置文件创建为一个 ConfigMap,--from-file=<目录>
$ k create configmap config-map3 --from-file=./configs
$ k describe cm config-map3
Name: config-map3
Namespace: test
Labels: <none>
Annotations: <none>

Data
====
app-copy.properties:
----
db.host mysql.db
db.port 3306

app.properties:
----
db.host mysql.db
db.port 3306


BinaryData
====

Events: <none>

# 事先写好标准的 configmap 的 yaml 文件,然后 kubectl create -f 创建
$ vim config-map4.yaml
apiVersion: v1
data:
db.host: mysql.db
db.port: "3306" # 数字一定要用双引号括起来
kind: ConfigMap
metadata:
name: config-map4

$ k apply -f config-map4.yaml
$ k describe cm config-map4
Name: config-map4
Namespace: test
Labels: <none>
Annotations: <none>

Data
====
db.host:
----
mysql.db
db.port:
----
3306

BinaryData
====

Events: <none>
  • 使用方法

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
73
## 通过环境变量使用
# 1.使用 valueFrom、configMapKeyRef、name、key 指定要用的 key:
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: centos
env:
- name: DB_HOST # 环境变量名称
valueFrom:
configMapKeyRef:
name: config-map4 # cm名称
key: db.host # cm中的key
# 2.通过 envFrom、configMapRef、name 使得 configmap 中的所有 key/value 对都自动变成环境变量
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: centos
envFrom:
configMapRef:
name: config-map4


## 在启动命令中引用
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: centos
command: ["/bin/sh"]
args: ["-c", "while true; do echo $(DB_HOST) $(DB_PORT) >> /out.txt; sleep 5; done"]
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: config-map4
key: db.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: config-map4
key: db.port


## 作为 volume 挂载使用
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: centos
command: ["/bin/sh"]
args: ["-c", "while true; do cat /tmp/config.properties >> /out.txt; sleep 5; done"]
volumeMounts:
- name: config-map3
mountPath: /tmp/config.properties # 挂载到的文件
subPath: app.properties # 被挂载的文件,即cm中的多个文件中的一个
volumes:
- name: config-map3
configMap:
name: config-map3

Secrets

  • Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。

  • Secret 可以以 Volume 或者环境变量的方式使用。

Secrets 类型

  • 创建 Secret 时,你可以使用 Secret 资源的 type 字段,或者与其等价的 kubectl 命令行参数(如果有的话)为其设置类型。

  • Kubernetes 提供若干种内置的类型,用于一些常见的使用场景。 针对这些类型,Kubernetes 所执行的合法性检查操作以及对其所实施的限制各不相同。

内置类型 用法
Opaque 用户定义的任意数据
kubernetes.io/service-account-token 服务账号令牌
kubernetes.io/dockercfg ~/.dockercfg 文件的序列化形式
kubernetes.io/dockerconfigjson ~/.docker/config.json 文件的序列化形式
kubernetes.io/basic-auth 用于基本身份认证的凭据
kubernetes.io/ssh-auth 用于 SSH 身份认证的凭据
kubernetes.io/tls 用于 TLS 客户端或者服务器端的数据
bootstrap.kubernetes.io/token 启动引导令牌数据
  • 通过为 Secret 对象的 type 字段设置一个非空的字符串值,你也可以定义并使用自己 Secret 类型(如果 type 值为空字符串,则被视为 Opaque 类型)。

  • 关于Secret类型的进一步说请查看https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/,以下示例仅对常用的Opaque进行说明。

创建 Secret

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
# 配置文件创建
$ echo -n 'my-app' | base64
bXktYXBw
$ echo -n '39528$vdg7Jb' | base64
Mzk1MjgkdmRnN0pi
# 配置文件
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYXBw # value必须是警告base64加密后的值
password: Mzk1MjgkdmRnN0pi

$ k apply -f secret.yaml
$ k describe secrets test-secret
Name: test-secret
Namespace: test
Labels: <none>
Annotations: <none>

Type: Opaque

Data
====
username: 6 bytes
password: 12 bytes

# 命令行创建,此时明文创建即可
$ kubectl create secret generic test-secret2 --from-literal='username=my-app' --from-literal='password=39528$vdg7Jb'

# 文件创建
$ kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub

使用 Secret

  • 创建一个可以通过卷访问 Secret 数据的 Pod

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
# secret-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
# name 必须与下面的卷名匹配
- name: secret-volume
mountPath: /etc/secret-volume
readOnly: true
# Secret 数据通过一个卷暴露给该 Pod 中的容器
volumes:
- name: secret-volume
secret:
secretName: test-secret

$ k apply -f secret-pod.yaml

# 输出包含两个文件,每个对应一个 Secret 数据条目
$ kubectl exec -i -t secret-test-pod -- ls /etc/secret-volume
password username
  • 映射 Secret 键到特定文件路径

    • 来自 mysecret 的键 username 可以在路径 /etc/foo/my-group/my-username 下供容器使用,而不是路径 /etc/foo/username
    • 来自该 Secret 的键 password 没有映射到任何路径
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
  • 使用来自 Secret 中的数据定义容器变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ k create secret generic backend-user --from-literal=backend-username='backend-admin'
# pod-single-secret-env-variable.yaml
apiVersion: v1
kind: Pod
metadata:
name: env-single-secret
spec:
containers:
- name: envars-test-container
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: backend-user
key: backend-username
$ k apply -f pod-single-secret-env-variable.yaml
$ k exec -i -t env-single-secret -- /bin/sh -c 'echo $SECRET_USERNAME'
  • 将 Secret 中的所有键值偶对定义为环境变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ k create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
# pod-secret-envFrom.yaml
apiVersion: v1
kind: Pod
metadata:
name: envfrom-secret
spec:
containers:
- name: envars-test-container
image: nginx
envFrom:
- secretRef:
name: test-secret
$ k apply -f pod-secret-envFrom.yaml
$ k exec -i -t envfrom-secret -- /bin/sh -c 'echo "username: $username\npassword: $password\n"'

service–svc

  • svc负责解决端口映射的问题

  • Kubernetes ServiceTypes 允许指定你所需要的 Service 类型。

  • 可用的 type 值及其行为有:

    • ClusterIP
      通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是你没有为服务显式指定 type 时使用的默认值。 你可以使用 Ingress 或者 Gateway API 向公众暴露服务。
    • NodePort
      通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 为了让节点端口可用,Kubernetes 设置了集群 IP 地址,这等同于你请求 type: ClusterIP 的服务。
    • LoadBalancer
      使用云提供商的负载均衡器向外部暴露服务。 Kubernetes 不直接提供负载均衡组件;你必须提供一个,或者将你的 Kubernetes 集群与云提供商集成。
    • ExternalName
      将服务映射到 externalName 字段的内容(例如,映射到主机名 api.foo.bar.example)。 该映射将集群的 DNS 服务器配置为返回具有该外部主机名值的 CNAME 记录。 无需创建任何类型代理。

NodePort

  • 可以让 kubernetes 在其所在节点上保留一个端口(所有节点上都使用相同的端口号),然后将传入的连接转发给 pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# svc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-nodeport
spec:
ports:
- name: test-nginx
port: 3080
targetPort: 80
nodePort: 32115 # 此处指定具体的端口,不能重复,如果没有配置则随机创建
selector:
app: test-nginx
type: NodePort

ClusterIP

  • 提供虚拟ip

1
2
3
4
5
6
# 基于delpoyment创建service
k expose deployment test-nginx --name svc-cluster-ip --port=3280 --target-port=80 --type=ClusterIP
# 不创建,只生成yaml文件
k expose deployment test-nginx --name svc-cluster-ip --port=3280 --target-port=80 --type=ClusterIP --dry-run=client -o yaml > svc-cluster-ip.yaml
# 基于yaml创建service
k apply -f svc-cluster-ip.yaml
  • Headless service clusterIP:基于statefulset创建service

    • 不提供虚拟ip,而是返回具体的pod地址,并且基于如下规则查找:
      ${podName}.${headlessServiceName即svcName}.${namespace}.${clusterDomainName}
      同一个namespace的pod访问时一般指定到${headlessServiceName}即可,跨namespace时需要指定到${namespace}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# svc-sts-web.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None # 这里必须设置为None
selector:
app: nginx

LoadBalancer

  • 相比 NodePort 方式可以通过任何节点的 指定 端口访问内部的 pod,LoadBalancer 方式拥有自己独一无二的可公开访问的 IP 地址;

  • LoadBalance 其实是 NodePort 的一种扩展,使得服务可以通过一个专用的负载均衡器来访问。

  • 如果是自建k8s,Kubernetes 没 有 为 裸 机 集 群 提 供 网 络 负 载 平 衡 器 的 实 现,所以需要安装一个LoadBalancer,比如 MetaLb 负载均衡,这里不做赘述。

  • EKS安装 AWS Load Balancer Controller 附加组件后即可提供支持。

可以基于pod直接创建svc

1
2
3
4
5
6
7
8
# 启动一个pod,默认的label是 run=nginx-app
kubectl run nginx-app --image=nginx --restart=Never --port=80
# 为pod添加标签
k label pod nginx-app app=nginx-app
# 创建一个svc的yaml文件,其selector为app: nginx-app,这里没有指定nodePort,创建时会随机分配一个端口
# 也可以修改生成的yaml文件,使其符合要求
kubectl create svc nodeport nginx-app --tcp=80:80 --dry-run -o yaml > svc_pod.yaml
k apply -f svc_pod.yaml

查看svc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看svc,注意查看TYPE,CLUSTER-IP ,EXTERNAL-IP,PORT显示的不同之处
> k get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx ClusterIP None <none> 80/TCP 130m app=nginx
svc-loadbalance-nginx LoadBalancer 172.20.57.83 aa39ab20daad5447da7ee7d283ab2a83-1210832584.ap-east-1.elb.amazonaws.com 3081:32116/TCP 10m app=test-nginx
svc-test-nginx NodePort 172.20.39.12 <none> 3080:32115/TCP 18h app=test-nginx
test-loadbalancer-new LoadBalancer 172.20.242.126 a2774e4dc02ad42cc97c54fc9968624b-882652598.ap-east-1.elb.amazonaws.com 3282:31212/TCP 10s app=test-nginx
test-nginx-new ClusterIP 172.20.144.96 <none> 3280/TCP 162m app=test-nginx

# 查看endpoint--ep
k get endpoints
> k get ep
NAME ENDPOINTS AGE
nginx 10.25.113.205:80,10.25.142.172:80,10.25.148.165:80 132m
svc-loadbalance-nginx 10.25.116.40:80,10.25.121.198:80,10.25.122.75:80 12m
svc-test-nginx 10.25.116.40:80,10.25.121.198:80,10.25.122.75:80 18h
test-loadbalancer-new 10.25.116.40:80,10.25.121.198:80,10.25.122.75:80 2m11s
test-nginx-new 10.25.116.40:80,10.25.121.198:80,10.25.122.75:80 164m

Ingress

  • Ingress将来自集群外部的 HTTP 和 HTTPS 路由暴露给集群 内的服务。流量路由由 Ingress 资源上定义的规则控制。

  • 私有k8s不提供Ingress,需要自行安装。

  • 基于aws-eks等云服务通过安装 AWS Load Balancer Controller 附加组件提供Ingress功能。

1
2
3
k get ing
k get ing -A
k get ing -n test

HPA:Horizontal Pod Autoscaler 自动弹性伸缩

  • 实现hpa的前提是k8s集群中部署 metrics-server,其可对node和pod占用CPU、内存的情况进行监控。

1
2
3
4
5
6
# 基于deployment创建hpa
k autoscale deployment test-nginx --max=3 --min=1 --cpu-percent=60
# 最多3个pod,最少1个pod,基于cpu使用情况,超过60%时进行扩容

# 查看hpa
k get hpa

其它命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 进入pod
k exec podName -it -- sh
k exec podName -it -- /bin/bash

# 监视变化 -w
k get deploy -w

# 不显示标题头 --no-headers=true
k get pods --no-headers=true

# 查看pod的日志输出
k logs podName

# 编辑一个资源,直接编辑已经部署的资源yaml
k edit deploy app

# 查看一个资源的部署情况
k describe deploy app