
kubectl 是 Kubernetes 集群的命令行工具, 通过 kubectl 能够对集群本身进行管理, 并能够在集群上进行容器化应用的安装部署。

comand: 指定要对资源执行的操作, 例如 create、 get、 describe 和 delete
TYPE: 指定资源类型, 资源类型是大小写敏感的, 开发者能够以单数、 复数和缩略的形式。 例如:

NAME: 指定资源的名称, 名称也大小写敏感的。 如果省略名称, 则会显示所有的资源,
例如:

k8s中文社区文档:http://docs.kubernetes.org.cn/php
k8s中文社区YAML:https://www.kubernetes.org.cn/1414.htmlhtml


Pod 是 k8s 系统中可以创建和管理的最小单元, 是资源对象模型中由用户创建或部署的最小资源对象模型, 也是在 k8s 上运行容器化应用的资源对象, 其他的资源对象都是用来支撑或者扩展 Pod 对象功能的, 比如控制器对象是用来管控 Pod 对象的, Service 或者Ingress 资源对象是用来暴露 Pod 引用对象的, PersistentVolume 资源对象是用来为 Pod提供存储等等, k8s 不会直接处理容器, 而是 Pod,Pod 是由一个或多个 container 组成
Pod 是 Kubernetes 的最重要概念, 每一个 Pod 都有一个特殊的被称为” 根容器“的 Pause容器。 Pause 容器对应的镜 像属于 Kubernetes 平台的一部分, 除了 Pause 容器, 每个 Pod还包含一个或多个紧密相关的用户业务容器
1. 资源共享
一个 Pod 里的多个容器可以共享存储和网络, 可以看作一个逻辑的主机。
共享的如namespace,cgroups 或者其他的隔离资源。
多个容器共享同一 network namespace, 由此在一个 Pod 里的多个容器共享 Pod 的 IP 和端口 namespace, 所以一个 Pod 内的多个容器之间可以通过 localhost 来进行通信,所需要注意的是不同容器要注意不要有端口冲突即可。
不同的 Pod 有不同的 IP,不同 Pod 内的多个容器之前通信, 不可以使用 IPC( 如果没有特殊指定的话) 通信, 通常情况下使用 Pod的 IP 进行通信。
一个 Pod 里的多个容器可以共享存储卷, 这个存储卷会被定义为 Pod 的一部分, 并且可以挂载到该 Pod 里的所有容器的文件系统上。
2. 生命周期短暂
Pod 属于生命周期比较短暂的组件, 比如, 当 Pod 所在节点发生故障, 那么该节点上的 Pod会被调度到其他节点, 但需要注意的是, 被重新调度的 Pod 是一个全新的 Pod,跟之前的Pod 没有半毛钱关系。
3. 平坦的网络
K8s 集群中的所有 Pod 都在同一个共享网络地址空间中, 也就是说每个 Pod 都可以通过其他 Pod 的 IP 地址来实现访问。

放入同一个namespace中



每个 Pod 都可以对其能使用的服务器上的计算资源设置限额, Kubernetes 中可以设置限额的计算资源有 CPU 与 Memory 两种, 其中 CPU 的资源单位为 CPU 数量,是一个绝对值而非相对值。 Memory 配额也是一个绝对值, 它的单 位是内存字节数。
Kubernetes 里, 一个计算资源进行配额限定需要设定以下两个参数: Requests 该资源最小申请数量, 系统必须满足要求 Limits 该资源最大允许使用的量, 不能突破, 当容器试图使用超过这个量的资源时, 可能会被 Kubernetes Kill 并重启


Pod 的重启策略包括 Always、 OnFailure 和 Never, 默认值是 Always


看下图层级关系
怎么把Pod分配到哪个Node节点上?



影响调度的因素1

对node节点,打标签命令
kubectl label node k8snode1 env_role=prod
kubectl label node k8snode1 env_role=dev
影响调度的因素2:根据标签
影响调度的因素3:污点、污点容忍

查看节点的污染情况
kubectl describe node k8smaster | grep Taint
为节点添加污点
kubectl taint node 【node】 key=value:污点的三个值
kubectl taint node k8snode1 env_role=yes:NoSchedule
删除污点
kubectl taint node k8snode env_role:NoSchedule-
污点容忍


在集群上管理和运行容器的对象
Deployment 是 Kubenetes v1.2 引入的新概念, 引入的目的是为了更好的解决 Pod 的编排问题, Deployment 内部使用了 Replica Set 来实现。
以Nginx为例
命令行,导出yaml文件
kubectl create deployment web --image=nginx --dry-run -o yaml > web.yaml
yaml 文件进行应用部署
kubectl apply -f web.yaml
对外暴露端口
kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=web1 -o yaml >web1.yaml
kubectl apply -f web1.yaml
查看
kubectl get pods,svc
kubectl apply -f web.yaml
web中,升级Nginx,保证升级过程中,服务不中断
kubectl set image deployment web nginx=nginx:1.15
查看升级状态
kubectl rollout status deployment web
web中,版本回滚
kubectl rollout history deployment web # 查看历史版本
kubectl rollout undo deployment web # 回滚到上一个版本
kubectl rollout undo deployment web --to-revision=2 #回滚到制定版本
弹性伸缩
增加更多的服务
kubectl scale deployment web --replicas=10

sts.yaml进行配置
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: nginx-statefulset
namespace: default
spec:
serviceName: nginx
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
1. kubectl apply -f sts.yaml # 创建
2. kubectl get pods # 查看
3. kubectl get service #查看service
所有node在同一pod中运行
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-test
labels:
app: filebeat
spec:
selector:
matchLabels:
app: filebeat
template:
metadata:
labels:
app: filebeat
spec:
containers:
- name: logs
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: varlog
mountPath: /tmp/log
volumes:
- name: varlog
hostPath:
path: /var/log
一次性任务
apiVersion: batch/v1
kind: Job #一次性任务
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
定时性任务
apiVersion: batch/v1beta1
kind: CronJob #定时任务
metadata:
name: hello
spec:
schedule: "*/1 * * * *" #定时任务的表达式
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
Service 是 Kubernetes 最核心概念, 通过创建 Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址, 并且将请求负载分发到后端的各个容器应用上

一般来说, 对外提供服务的应用程序需要通过某种机制来实现, 对于容器应用最简便的方式就是通过 TCP/IP 机制及 监听 IP 和端口号来实现。 创建一个基本功能的 Service
apiVersion: v1
kind: ReplicationController metadata:
name: mywebapp spec:
replicas: 2 template:
metadata:
name: mywebapp labels:
app: mywebapp spec:
containers:
-name: mywebapp image: tomcat ports:
-containerPort: 8080
我们可以通过 kubectl get pods -l app=mywebapp -o yaml | grep podIP 来获取Pod 的 IP 地址和端口号来访问 Tomcat 服务, 但是直接通过 Pod 的 IP 地址和端口访问应用服务是不可靠的, 因为当 Pod 所在的 Node 发生故障时, Pod 将被 kubernetes 重新调度到另一台 Node, Pod 的地址会发生改变。 我们可以通过配置文件来定义 Service, 再 通过kubectl create 来创建, 这样可以通过 Service 地址来访问后端的 Pod
apiVersion: v1 kind: Service metadata:
name: mywebAppService spec:
ports:
- port: 8081
targetPort: 8080 selector:
app: mywebapp
多端口 Service
有时一个容器应用也可能需要提供多个端口的服务, 那么在 Service 的定义中也可以相应地设置为将多个端口对应 到多个应用服务。
apiVersion: v1 kind: Service metadata:
name: mywebAppService spec:
ports:
- port: 8080
targetPort: 8080 name: web
- port: 8005
targetPort: 8005 name: management
selector:
app: mywebapp
外部服务 Service
在某些特殊环境中, 应用系统需要将一个外部数据库作为后端服务进行连接, 或将另一个集群或 Namespace 中的 服务作为服务的后端, 这时可以通过创建一个无 Label Selector的 Service 来实现。

apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
变量的形式挂在到pod容器中
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx
env:
- name: SECRET_USERNAME # 变量
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD # 变量
valueFrom:
secretKeyRef:
name: mysecret
key: password
以volume形式挂在到pod中
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx
volumeMounts: # 挂载
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
ConfigMap 功能在 Kubernetes1.2 版本中引入, 许多应用程序会从配置文件、 命令行参数或环境变量中读取配 置信息。 ConfigMap API给我们提供了向容器中注入配置信息的机制, ConfigMap 可以被用来保存单个属性, 也 可以用来保存整个配置文件或者 JSON 二进制大对象

创建配置文件redis.properties
redis.host=127.0.0.1
redis.port=6379
redis.password=123456
创建configmap
kubectl create configmap redis-config --from-file=redis.properties
查看
kubectl get cm
以volume挂载
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: busybox
image: busybox
command: [ "/bin/sh","-c","cat /etc/config/redis.properties" ]
volumeMounts: # 挂载
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: redis-config
restartPolicy: Never
以变量形式挂载
创建myconfig.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfig
namespace: default
data:
special.level: info
special.type: hello
myconfig.yaml以变量形式挂载config-var.yaml到pod
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: busybox
image: busybox
command: [ "/bin/sh", "-c", "echo $(LEVEL) $(TYPE)" ]
env:
- name: LEVEL # 变量
valueFrom:
configMapKeyRef:
name: myconfig
key: special.level
- name: TYPE # 变量
valueFrom:
configMapKeyRef:
name: myconfig
key: special.type
restartPolicy: Never
认证
鉴权
准入控制

RBAC(Role-Based Access Control, 基于角色的访问控制)在 k8s v1.5 中引入, 在 v1.6 版本时升级为 Beta 版本, 并成为 kubeadm 安装方式下的默认选项, 相对于其他访问控制方式,新的 RBAC 具有如下优势:
--authorization-mode=RBAC
查看命名空间
kubectl get ns
创建命名空间
kubectl create ns roledemo
在新创建的命名空间下创建一个pod
kubectl run nginx --image=nginx -n roledemo
创建一个角色rbac.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: ctnrs
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"] # pod资源
verbs: ["get", "watch", "list"] # 权限
执行
kubectl apply -f rbac.yaml
创建角色绑定,rabc-rolebinding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: roledemo # 名称空间
subjects:
- kind: User
name: mary # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
执行
kubectl apply -f rabc-rolebinding.yaml
查看角色绑定
kubectl get role,rolebinding -n roledemo
使用证书识别身份,执行一个脚本文件
cat > mary-csr.json <<EOF
{
"CN": "mary",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes mary-csr.json | cfssljson -bare mary
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://192.168.31.63:6443 \
--kubeconfig=mary-kubeconfig
kubectl config set-credentials mary \
--client-key=mary-key.pem \
--client-certificate=mary.pem \
--embed-certs=true \
--kubeconfig=mary-kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user=mary \
--kubeconfig=mary-kubeconfig
kubectl config use-context default --kubeconfig=mary-kubeconfig
RBAC 引入了 4 个新的顶级资源对象:
同其他 API 资源对象一样, 用户可以使用 kubectl 或者 API 调用等方式操作这些资源对象。
1.角色(Role)
一个角色就是一组权限的集合, 这里的权限都是许可形式的, 不存在拒绝的规则。 在一个命名空间中, 可以用角色来定义一个角色, 如果是集群级别的, 就需要使用 ClusterRole了。 角色只能对命名空间内的资源进行授权, 下面的例子中定义的角色具备读取 Pod 的权限:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # 空字符串表示核心 API 群
resource: ["pods"]
verbs: ["get", "watch", "list"]
rules 中的参数说明:
2.集群角色(ClusterRole)
集群角色除了具有和角色一致的命名空间内资源的管理能力, 因其集群级别的范围, 还可以用于以下特殊元素的授权。
下面的集群角色可以让用户有权访问任意一个或所有命名空间的 secrets:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# name: secret-reader
# ClusterRole 不受限于命名空间, 所以省略了 namespace name 的定义
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
3.角色绑定(RoleBinding)和集群角色绑定(ClusterRoleBinding)
角色绑定或集群角色绑定用来把一个角色绑定到一个目标上, 绑定目标可以是 User、Group 或者 Service Account。 使用 RoleBinding 为某个命名空间授权,ClusterRoleBinding 为集群范围内授权。RoleBinding 可以引用 Role 进行授权, 下例中的 RoleBinding 将在 default 命名空间中把pod-reader 角色授予用户 jane, 可以让 jane 用户读取 default 命名空间的 Pod:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
RoleBinding 也可以引用 ClusterRole, 对属于同一命名空间内 ClusterRole 定义的资源主体进行授权。 一种常见的做法是集群管理员为集群范围预先定义好一组角色(ClusterRole),然后在多个命名空间中重复使用这些 ClusterRole。使用 RoleBinding 绑定集群角色 secret-reader, 使 dave 只能读取 development 命名空间中的 secret:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-secrets
namespace: development
subjects:
- kind: User
name: dave
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
集群角色绑定中的角色只能是集群角色, 用于进行集群级别或者对所有命名空间都生效授权。 允许 manager 组的用户读取任意 namespace 中的 secret
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io

创建nginx应用,对外暴露端口
kubectl create deployment web --image=nginx
创建一个service,暴露端口,方式NodePort
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
使用Ingress方式暴露端口
下载一个ingress-controller文件,部署
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx #名称
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses/status
verbs:
- update
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: nginx-ingress-role
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
resourceNames:
# Defaults to "-"
# Here: "-"
# This has to be adapted if you change either parameter
# when launching the nginx-ingress-controller.
- "ingress-controller-leader-nginx"
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: nginx-ingress-role-nisa-binding
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress-role
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nginx-ingress-clusterrole-nisa-binding
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nginx-ingress-clusterrole
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
hostNetwork: true
# wait up to five minutes for the drain of connections
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
kubernetes.io/os: linux
containers:
- name: nginx-ingress-controller
image: lizhenliang/nginx-ingress-controller:0.30.0
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
securityContext:
allowPrivilegeEscalation: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
# www-data -> 101
runAsUser: 101
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
---
apiVersion: v1
kind: LimitRange
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
limits:
- min:
memory: 90Mi
cpu: 100m
type: Container
执行
kubectl apply -f ingress-controller.yaml
创建Ingress规则
ingress-conf.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: example.ingredemo.com # 域名
http:
paths:
- path: /
backend:
serviceName: web #创建的service名字
servicePort: 80 # 暴露的端口
执行
kubectl apply -f ingress-conf.yaml
查看
kubectl get pods -n ingress-nginx -o wide
在Windows系统host文件中添加域名访问规则
访问
kubectl get pods
kubectl get svc
kubectl get ingress