目次
1. 名前空間
2. ポッド
3. ラベル
4.展開
いくつかの基本概念の簡単で実践的な操作を通じて、名前空間、ポッド、ラベル、デプロイメント、サービスを含む kubernetes (k8s) のエントリー操作が完了します。これらの操作を使用すると、kubernetes クラスター内のサービスの簡単なデプロイとアクセスを実装できますが、kubernetes をより適切に使用したい場合は、これらのリソースの詳細と原則を詳しく調べる必要があります。
1.名前空間
名前空間は kubernetes システムにおいて非常に重要なリソースであり、その主な機能は複数環境のリソース分離やマルチテナントのリソース分離を実現することです。
デフォルトでは、kubernetes クラスター内のすべての Pod が相互にアクセスできます。ただし、実際には、2 つの Pod が相互にアクセスすることを許可したくない場合は、2 つの Pod を異なる名前空間に分割できます。Kubernetes は、クラスター内のリソースを異なる名前空間に割り当てることで論理「グループ」を形成し、異なるグループ内のリソースの分離した使用と管理を容易にします。
kubernetes 承認メカニズムを通じて、異なる名前空間を異なるテナントに引き渡して管理できるため、マルチテナントのリソース分離が実現します。このとき、kubernetes のリソース クォータ メカニズムを組み合わせて、CPU 使用率やメモリ使用量など、さまざまなテナントが占有できるリソースを制限し、テナントの利用可能なリソースの管理を実現することもできます。
クラスターが開始されると、kubernetes はデフォルトでいくつかの名前空間を作成します。
[root@master ~]# kubectl 名前空間を取得 名前 ステータス 年齢 デフォルトのアクティブ 45h # ネームスペースを指定していないすべてのオブジェクトはデフォルトのネームスペースに割り当てられます kube-node-lease アクティブ 45 時間 # クラスター ノード間のハートビート メンテナンス、v1.13で導入 kube-public Active 45h # この名前空間のリソースには、誰でも (認証されていないユーザーを含む) アクセスできます。 kube-system Active 45h #Kubernetesシステムによって作成されたすべてのリソースはこの名前空間にあります |
名前空間リソースの具体的な操作を見てみましょう。
1.見る
シェル # 1すべての ns コマンドを表示します: kubectl get ns [root@master ~]# kubectl get ns 名前 ステータス 年齢 デフォルト アクティブ 45h kube-node-lease アクティブ 45h kube-public アクティブ 45h kube-system アクティブ 45h # 2 指定された ns を表示しますコマンド: kubectl get ns ns name [root@master ~]# kubectl get nsdefault NAME STATUS AGE default Active 45h # 3 出力形式を指定します コマンド: kubectl get ns ns name -o formatparameter # kubernetes では多くの形式がサポートされています。比較 一般的なものは、wide、json、yaml です [root@master ~]# kubectl get ns default -o yaml apiVersion: v1 kind: Namespace metadata: CreationTimestamp: "2020-04-05T04:44:16Z" 名前: デフォルトの リソースバージョン: "151" selfLink: /api/v1/namespaces/default uid: 7405f73a-e486-43d4-9db6-145f1409f090 仕様: ファイナライザー: - kubernetes ステータス: フェーズ: アクティブ # 4 ns 詳細の表示コマンド: kubectl description ns ns name [root@master ~]# kubectl description nsdefault 名前: デフォルト ラベル: <なし> 注釈: <なし> ステータス: アクティブ # アクティブな名前空間は使用中です 終了中の名前空間は削除されています # ResourceQuota 名前空間のリソース制限 # LimitRange は名前空間内の各コンポーネントのリソース制限、 リソース割り当てなし、 LimitRange リソースなし。 |
2.作成
Shell # 创建namespace [root@master ~]# kubectl create ns dev namespace/dev created |
3、删除
Shell # 删除namespace [root@master ~]# kubectl delete ns dev namespace "dev" deleted |
4、配置方式
先准备一个yaml文件:ns-dev.yaml
apiVersion: v1 kind: Namespace metadata: name: dev |
然后就可以执行对应的创建和删除命令了:
创建:kubectl create -f ns-dev.yaml
删除:kubectl delete -f ns-dev.yaml
二、Pod
Pod是kubernetes集群进行管理的最小单元,程序要运行必须部署在容器中,而容器必须存在于Pod中。
Pod可以认为是容器的封装,一个Pod中可以存在一个或者多个容器。
kubernetes在集群启动之后,集群中的各个组件也都是以Pod方式运行的。可以通过下面命令查看:
SQL [root@master ~]# kubectl get pod -n kube-system NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-6955765f44-68g6v 1/1 Running 0 2d1h kube-system coredns-6955765f44-cs5r8 1/1 Running 0 2d1h kube-system etcd-master 1/1 Running 0 2d1h kube-system kube-apiserver-master 1/1 Running 0 2d1h kube-system kube-controller-manager-master 1/1 Running 0 2d1h kube-system kube-flannel-ds-amd64-47r25 1/1 Running 0 2d1h kube-system kube-flannel-ds-amd64-ls5lh 1/1 Running 0 2d1h kube-system kube-proxy-685tk 1/1 Running 0 2d1h kube-system kube-proxy-87spt 1/1 Running 0 2d1h kube-system kube-scheduler-master 1/1 Running 0 2d1h |
1、创建并运行
kubernetes没有提供单独运行Pod的命令,都是通过Pod控制器来实现的
Shell # 命令格式: kubectl run (pod控制器名称) [参数] # --image 指定Pod的镜像 # --port 指定端口 # --namespace 指定namespace [root@master ~]# kubectl run nginx --image=nginx:1.17.1 --port=80 --namespace dev deployment.apps/nginx created |
2、查看pod信息
Shell # 查看Pod基本信息 [root@master ~]# kubectl get pods -n dev NAME READY STATUS RESTARTS AGE nginx-5ff7956ff6-fg2db 1/1 Running 0 43s # 查看Pod的详细信息 [root@master ~]# kubectl describe pod nginx-5ff7956ff6-fg2db -n dev Name: nginx-5ff7956ff6-fg2db Namespace: dev Priority: 0 Node: node1/192.168.109.101 Start Time: Wed, 08 Apr 2020 09:29:24 +0800 Labels: pod-template-hash=5ff7956ff6 run=nginx Annotations: <none> Status: Running IP: 10.244.1.23 IPs: IP: 10.244.1.23 Controlled By: ReplicaSet/nginx-5ff7956ff6 Containers: nginx: Container ID: docker://4c62b8c0648d2512380f4ffa5da2c99d16e05634979973449c98e9b829f6253c Image: nginx:1.17.1 Image ID: docker-pullable://nginx@sha256:485b610fefec7ff6c463ced9623314a04ed67e3945b9c08d7e53a47f6d108dc7 Port: 80/TCP Host Port: 0/TCP State: Running Started: Wed, 08 Apr 2020 09:30:01 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-hwvvw (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-hwvvw: Type: Secret (a volume populated by a Secret) SecretName: default-token-hwvvw Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned dev/nginx-5ff7956ff6-fg2db to node1 Normal Pulling 4m11s kubelet, node1 Pulling image "nginx:1.17.1" Normal Pulled 3m36s kubelet, node1 Successfully pulled image "nginx:1.17.1" Normal Created 3m36s kubelet, node1 Created container nginx Normal Started 3m36s kubelet, node1 Started container nginx |
3、访问pod信息
Shell # 获取podIP [root@master ~]# kubectl get pods -n dev -o wide NAME READY STATUS RESTARTS AGE IP NODE ... nginx-5ff7956ff6-fg2db 1/1 Running 0 190s 10.244.1.23 node1 ... #访问POD [root@master ~]# curl http://10.244.1.23:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> </head> <body> <p><em>Thank you for using nginx.</em></p> </body> </html> |
4、删除指定Pod
Shell # 删除指定Pod [root@master ~]# kubectl delete pod nginx-5ff7956ff6-fg2db -n dev pod "nginx-5ff7956ff6-fg2db" deleted # 此时,显示删除Pod成功,但是再查询,发现又新产生了一个 [root@master ~]# kubectl get pods -n dev NAME READY STATUS RESTARTS AGE nginx-5ff7956ff6-jj4ng 1/1 Running 0 21s # 这是因为当前Pod是由Pod控制器创建的,控制器会监控Pod状况,一旦发现Pod死亡,会立即重建 # 此时要想删除Pod,必须删除Pod控制器 # 先来查询一下当前namespace下的Pod控制器 [root@master ~]# kubectl get deploy -n dev NAME READY UP-TO-DATE AVAILABLE AGE nginx 1/1 1 1 9m7s # 接下来,删除此PodPod控制器 [root@master ~]# kubectl delete deploy nginx -n dev deployment.apps "nginx" deleted # 稍等片刻,再查询Pod,发现Pod被删除了 [root@master ~]# kubectl get pods -n dev No resources found in dev namespace. |
5、配置操作
创建一个pod-nginx.yaml,内容如下:
Shell apiVersion: v1 kind: Pod metadata: name: nginx namespace: dev spec: containers: - image: nginx:1.17.1 name: pod ports: - name: nginx-port containerPort: 80 protocol: TCP |
然后就可以执行对应的创建和删除命令了:
创建:kubectl create -f pod-nginx.yaml
删除:kubectl delete -f pod-nginx.yaml
三、Label
1、介绍
Label是kubernetes系统中的一个重要概念。它的作用就是在资源上添加标识,用来对它们进行区分和选择。
Label的特点:
- 一个Label会以key/value键值对的形式附加到各种对象上,如Node、Pod、Service等等
- 一个资源对象可以定义任意数量的Label ,同一个Label也可以被添加到任意数量的资源对象上去
- Label通常在资源对象定义时确定,当然也可以在对象创建后动态添加或者删除
可以通过Label实现资源的多维度分组,以便灵活、方便地进行资源分配、调度、配置、部署等管理工作。
一些常用的Label 示例如下: 版本标签:"version":"release", "version":"stable"...... 环境标签:"environment":"dev","environment":"test","environment":"pro" 架构标签:"tier":"frontend","tier":"backend" |
标签定义完毕之后,还要考虑到标签的选择,这就要使用到Label Selector,即:
Label用于给某个资源对象定义标识
Label Selector用于查询和筛选拥有某些标签的资源对象
当前有两种Label Selector:
基于等式的Label Selector
name = slave: 选择所有包含Label中key="name"且value="slave"的对象
env != production: 选择所有包括Label中的key="env"且value不等于"production"的对象
基于集合的Label Selector
name in (master, slave): 选择所有包含Label中的key="name"且value="master"或"slave"的对象
name not in (frontend): 选择所有包含Label中的key="name"且value不等于"frontend"的对象
标签的选择条件可以使用多个,此时将多个Label Selector进行组合,使用逗号","进行分隔即可。例如:
name=slave,env!=production
name not in (frontend),env!=production
2、命令方式
Shell # 为pod资源打标签 [root@master ~]# kubectl label pod nginx-pod version=1.0 -n dev pod/nginx-pod labeled # 为pod资源更新标签 [root@master ~]# kubectl label pod nginx-pod version=2.0 -n dev --overwrite pod/nginx-pod labeled # 查看标签 [root@master ~]# kubectl get pod nginx-pod -n dev --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-pod 1/1 Running 0 10m version=2.0 # 筛选标签 [root@master ~]# kubectl get pod -n dev -l version=2.0 --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-pod 1/1 Running 0 17m version=2.0 [root@master ~]# kubectl get pod -n dev -l version!=2.0 --show-labels No resources found in dev namespace. #删除标签 [root@master ~]# kubectl label pod nginx-pod version- -n dev pod/nginx-pod labeled |
3、配置方式
Shell apiVersion: v1 kind: Pod metadata: name: nginx namespace: dev labels: version: "3.0" env: "test" spec: containers: - image: nginx:1.17.1 name: pod ports: - name: nginx-port containerPort: 80 protocol: TCP |
然后就可以执行对应的更新命令了:kubectl apply -f pod-nginx.yaml
四、Deployment
在kubernetes中,Pod是最小的控制单元,但是kubernetes很少直接控制Pod,一般都是通过Pod控制器来完成的。Pod控制器用于pod的管理,确保pod资源符合预期的状态,当pod的资源出现故障时,会尝试进行重启或重建pod。
在kubernetes中Pod控制器的种类有很多,本章节只介绍一种:Deployment。
1、命令操作
Shell # 命令格式: kubectl run deployment名称 [参数] # --image 指定pod的镜像 # --port 指定端口 # --replicas 指定创建pod数量 # --namespace 指定namespace [root@master ~]# kubectl run nginx --image=nginx:1.17.1 --port=80 --replicas=3 -n dev deployment.apps/nginx created # 查看创建的Pod [root@master ~]# kubectl get pods -n dev NAME READY STATUS RESTARTS AGE nginx-5ff7956ff6-6k8cb 1/1 Running 0 19s nginx-5ff7956ff6-jxfjt 1/1 Running 0 19s nginx-5ff7956ff6-v6jqw 1/1 Running 0 19s # 查看deployment的信息 [root@master ~]# kubectl get deploy -n dev NAME READY UP-TO-DATE AVAILABLE AGE nginx 3/3 3 3 2m42s # UP-TO-DATE:成功升级的副本数量 # AVAILABLE:可用副本的数量 [root@master ~]# kubectl get deploy -n dev -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR nginx 3/3 3 3 2m51s nginx nginx:1.17.1 run=nginx # 查看deployment的详细信息 [root@master ~]# kubectl describe deploy nginx -n dev Name: nginx Namespace: dev CreationTimestamp: Wed, 08 Apr 2020 11:14:14 +0800 Labels: run=nginx Annotations: deployment.kubernetes.io/revision: 1 Selector: run=nginx Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: run=nginx Containers: nginx: Image: nginx:1.17.1 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: nginx-5ff7956ff6 (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 5m43s deployment-controller Scaled up replicaset nginx-5ff7956ff6 to 3 # 删除 [root@master ~]# kubectl delete deploy nginx -n dev deployment.apps "nginx" deleted
|
2、配置操作
创建一个deploy-nginx.yaml,内容如下:
Shell apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: dev spec: replicas: 3 selector: matchLabels: run: nginx template: metadata: labels: run: nginx spec: containers: - image: nginx:1.17.1 name: nginx ports: - containerPort: 80 protocol: TCP |
然后就可以执行对应的创建和删除命令了:
创建:kubectl create -f deploy-nginx.yaml
删除:kubectl delete -f deploy-nginx.yaml
五、service
通过上节课的学习,已经能够利用Deployment来创建一组Pod来提供具有高可用性的服务。
虽然每个Pod都会分配一个单独的Pod IP,然而却存在如下两问题:
- Pod IP 仅仅是集群内可见的虚拟IP,外部无法访问
这样对于访问这个服务带来了难度。因此,kubernetes设计了Service来解决这个问题。
Service可以看作是一组同类Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。
操作一:创建集群内部可访问的Service
Shell # 暴露Service [root@master ~]# kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev service/svc-nginx1 exposed # 查看service [root@master ~]# kubectl get svc svc-nginx -n dev -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR svc-nginx1 ClusterIP 10.109.179.231 <none> 80/TCP 3m51s run=nginx # 这里产生了一个CLUSTER-IP,这就是service的IP,在Service的生命周期中,这个地址是不会变动的 # 可以通过这个IP访问当前service对应的POD [root@master ~]# curl 10.109.179.231:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> </head> <body> <h1>Welcome to nginx!</h1> ....... </body> </html> |
操作二:创建集群外部也可访问的Service
Shell # 上面创建的Service的type类型为ClusterIP,这个ip地址只用集群内部可访问 # 如果需要创建外部也可以访问的Service,需要修改type为NodePort [root@master ~]# kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev service/svc-nginx2 exposed # 此时查看,会发现出现了NodePort类型的Service,而且有一对Port(80:31928/TC) [root@master ~]# kubectl get svc svc-nginx-1 -n dev -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR svc-nginx2 NodePort 10.100.94.0 <none> 80:31928/TCP 9s run=nginx # 接下来就可以通过集群外的主机访问 节点IP:31928访问服务了 # 例如在的电脑主机上通过浏览器访问下面的地址 http://192.168.109.100:31928/ |
删除Service
Shell [root@master ~]# kubectl delete svc svc-nginx-1 -n dev service "svc-nginx-1" deleted |
配置方式
创建一个svc-nginx.yaml,内容如下:
Shell apiVersion: v1 kind: Service metadata: name: svc-nginx namespace: dev spec: clusterIP: 10.109.179.231 ports: - port: 80 protocol: TCP targetPort: 80 selector: run: nginx type: ClusterIP |
然后就可以执行对应的创建和删除命令了:
创建:kubectl create -f svc-nginx.yaml
删除:kubectl delete -f svc-nginx.yaml