1019Namespace ,Contexts ,Kubernetes Pod

内容

  1. Namespace and Contexts
  2. Kubernetes Pod

Namespace and Contexts

学习参考:Namespace

Namespace 介绍

**问题:**多个用户使用同一个Kubernetes Cluster, 如何将他们创建的资源隔离开呢? 答案:Namespace ,简写ns,也称之为 project,代表资源集合,用于分组集群资源。Kubernetes 使用 Namespace 可以将一个物理的 Cluster 逻辑上划分成多个资源集合, 每个集合就是一个Namespace。 不同Namespace 里的资源是完全隔离的。 Kubernetes 默认创建以下Namespace:

  • default: 创建资源时如果不指定Namespace, 将被放到这个Namespace中。
  • kube-system: Kubernetes 自己创建的系统资源将放到这个Namespace中。
  • kube-public:该命名空间中所有对象可以被所有用户(包括未验证身份的用户)读取。
  • kube-node-lease :该命名空间含有与每个节点关联的Lease对象。节点租用允许kubelet发送heartbeat(心跳),以便控制平面能检测节点故障。 思考:所有对象都属于 Namespace 吗? **答:**大多数Kubernetes资源(例如 pod、services、pvc等)都属于某个Namespace,但 Namespace 资源本身并不在 Namespace 中,更低级别资源(如Node和persistentVolumes)也不在任何Namespace中。

Namespace 管理

bash 复制代码
# 查看Namespace清单
root@master30:~# kubectl get ns
NAME              STATUS   AGE
default           Active   7d4h
kube-node-lease   Active   7d4h
kube-public       Active   7d4h
kube-system       Active   7d4h

# 获取Namespace资源yaml格式定义文件
root@master30:~# kubectl get ns default -o yaml

# 创建Namespace
root@master30:~# kubectl create ns laodi
# 注意:命名空间名称满足正则表达式[a-z0-9]([-a-z0-9]*[a-z0-9])?,最大长度为63位

# 直接编辑Namespace
root@master30:~# kubectl edit ns laodi

# 查看Namespace详细信息
root@master30:~# kubectl describe ns laodi
Name:         laodi
Labels:       <none>
Annotations:  <none>
Status:       Active
No resource quota.
No LimitRange resource.

# 删除Namespace
root@master30:~# kubectl delete ns laodi
namespace "laodi" deleted
# 注意:
# 删除一个namespace会自动删除该namespace中所有资源。
# default和kube-system命名空间不可删除。

Namespace 还可以通过 yaml 文件创建。

bash 复制代码
# ns-laodi.yaml 定义namespace资源的yaml文件
apiVersion: v1
kind: Namespace
metadata:
  name: laodi
# 通过yaml文件创建namespace
root@master30:~# kubectl apply -f ns-laodi.yaml 
namespace/laodi created

操作特定ns中对象,需要使用选项-n指定ns,例如:

bash 复制代码
# 在laodi命名空间运行nginx pod
root@master30:~# kubectl run web --image=nginx -n laodi
pod/web created

# 查看laodi命名空间下pod详细信息,-o wide展示节点、ip等信息
root@master30:~# kubectl get pod -n laodi -o wide
NAME   READY   STATUS    RESTARTS   AGE     IP               NODE                   NOMINATED NODE   READINESS GATES
web    1/1     Running   0          39s   10.224.113.129   worker32.laodi.cloud   <none>           <none>

# curl访问pod内部nginx服务,grep过滤nginx关键字
root@master30:~# curl -s 10.224.113.129  | grep nginx
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
<p>If you see this page, nginx is successfully installed and working.
<a href="[https://nginx.org/](https://nginx.org/)">nginx.org</a>.<br />
<a href="[https://community.nginx.org/](https://community.nginx.org/)">community.nginx.org</a>.<br />
<a href="[https://f5.com/nginx](https://f5.com/nginx)">f5.com/nginx</a>.</p>
<p><em>Thank you for using nginx.</em></p>

Namespace 切换

kubernetes 自带工具

查看当前所在ns

bash 复制代码
# 查看所有上下文信息
root@master30:~# kubectl config get-contexts 
CURRENT   NAME                          CLUSTER      AUTHINFO          NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin

此时NAMESPACE列对应的属性为空,不属于任何NAMESPACE。

设置默认ns

bash 复制代码
# 修改当前上下文的默认namespace为laodi
root@master30:~# kubectl config set-context --current --namespace=laodi
Context "kubernetes-admin@kubernetes" modified.

# 再次查看上下文,确认默认namespace变更
root@master30:~# kubectl config get-contexts 
CURRENT   NAME                          CLUSTER      AUTHINFO        NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   laodi

此时,NAMESPACE 列对应的属性为 laodi。

kubens-第三方工具

kubens 安装

bash 复制代码
# 下载kubectx项目源码压缩包,kubens属于该项目工具
root@master30:~# wget [https://codeload.github.com/ahmetb/kubectx/zip/refs/heads/master](https://codeload.github.com/ahmetb/kubectx/zip/refs/heads/master) -O kubectx.zip

# 解压压缩包
root@master30:~# unzip kubectx.zip

# 查看解压后目录内容
root@master30:~# ls kubectx-master/
CONTRIBUTING.md  README.md  completion  go.sum  internal  kubens
LICENSE          cmd        go.mod      img     kubectx   test

# 将kubens二进制复制到系统bin目录,全局可执行
root@master30:~# cp kubectx-master/kubens /usr/local/bin/

# 添加可执行权限
root@master30:~# chmod +x /usr/local/bin/kubens

# 拷贝bash自动补全脚本到系统补全目录
root@master30:~# cp kubectx-master/completion/kubens.bash /etc/bash_completion.d/

# 加载补全脚本,生效补全功能
root@master30:~# source /etc/bash_completion.d/kubens.bash

kubens 命令使用

bash 复制代码
# 查看kubens帮助文档
root@master30:~# kubens -h
USAGE:
  kubens                    : list the namespaces in the current context
  kubens <NAME>             : change the active namespace of current context
  kubens -                  : switch to the previous namespace in this context
  kubens -c, --current      : show the current namespace
  kubens -h,--help          : show this message

# 列出集群全部namespace
root@master30:~# kubens 
default
kube-node-lease
kube-public
kube-system
laodi

# 切换当前上下文默认namespace为kube-system
root@master30:~# kubens kube-system

# 查看上下文确认切换结果
root@master30:~# kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   kube-syste

# 不指定-n,直接获取当前默认namespace下pod
root@master30:~# kubectl get pods
NAME                                          READY   STATUS    RESTARTS   AGE
calico-kube-controllers-7cb4fd5784-dqv6n      1/1     Running   0          19m
calico-node-5k2bp                             1/1     Running   0          18m
calico-node-6vpt6                             1/1     Running   0          19m
calico-node-7x82d                             1/1     Running   0          19m
coredns-66f779496c-h89xx                      1/1     Running   0          19m
coredns-66f779496c-zqqxd                      1/1     Running   0          19m
etcd-master30.laodi.cloud                      1/1     Running   2          19m
kube-apiserver-master30.laodi.cloud            1/1     Running   2          19m
kube-controller-manager-master30.laodi.cloud   1/1     Running   2          19m
kube-proxy-7l9pr                              1/1     Running   0          19m
kube-proxy-9djwp                              1/1     Running   0          19m
kube-proxy-n2bk9                              1/1     Running   0          18m
kube-scheduler-master30.laodi.cloud            1/1     Running   2          19m

自定义脚本

bash 复制代码
#!/bin/bash
# 使用帮助输出函数
function usage(){
  echo "$0 [namespace]
1. 没有namespace参数时,显示namespace清单
2. namespace必须是集群中存在的namespace"
}

# 获取当前上下文配置的namespace
namespace=$(kubectl config get-contexts | awk '/\*/{print $5}')
# 如果为空,赋值为default
if [ -z "$namespace" ];then
  namespace=default
fi

# 无参数,打印namespace列表,标记当前ns
if [ $# -eq 0 ];then
  kubectl get ns | awk '{print "  "$1}' | sed "s/^  $namespace/\* $namespace/"
  exit 1
fi

# 传入1个参数,做namespace切换
if [ $# -eq 1 ];then
  # 判断传入的namespace是否真实存在集群中
  if kubectl get ns | awk '$1 !~ "NAME" {print $1}' | grep -qx "$1" &>/dev/null;then
    # 修改当前上下文默认namespace,屏蔽标准输出
    kubectl config set-context --current --namespace $1 > /dev/null
    echo "当前namespace设置为:$1"
  else
    usage  
  fi
fi

Cluster 切换

~/.kube/config 详解

单集群配置

获取凭据文件内容(不显示敏感信息):

bash 复制代码
# 查看kubeconfig配置,敏感证书信息会做省略
root@master30:~# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED # ca证书base64编码,DATA+OMITTED代表省略敏感内容
    server: [https://10.1.8.30:6443](https://10.1.8.30:6443) # k8s apiserver访问地址
  name: kubernetes # 集群名称
contexts:
- context:
    cluster: kubernetes # 关联上面定义的集群名
    namespace: kube-system # 当前上下文默认namespace
    user: kubernetes-admin # 关联下面定义的用户
  name: kubernetes-admin@kubernetes # 上下文名称
current-context: kubernetes-admin@kubernetes # 当前激活使用的上下文
kind: Config
preferences: {}
users:
- name: kubernetes-admin # 用户名称
  user:
    client-certificate-data: DATA+OMITTED # 用户客户端证书base64
    client-key-data: DATA+OMITTED # 用户私钥base64

配置文件示例:

yaml 复制代码
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1EUXdNakExTURZd05Wb1hEVE15TURNek1EQTFNRFl3TlZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTHg5ClZnNGUyR3dUTkVUaUowTjBqV09hZ2NvQVRnclFzVXVjWU1Jb281YWFZZGtTZGY2amdJanhTeEtNTmZyL3MrQWQKems5S25CL2UwS0ZxSEJwOEhsQy9VZ0JTK1V2THl6b2VuWVNFM29MWmJzdDhwY1JXL0ZWQVdQckRkS1VhcTdJcApyVXpvQlRTSHRHSEluNitLR1htZ3BwWkdLK3pRT2pjTWYyT2IxOGZ0NDZDbXNFT24rMmhKZk13eHBUd3k0dEgvCktteWhnVStYUys1c0Z5L0N2R1gwbUEzbWpzeHZ4VnFmamQ0T2F0RVVhamN5aERVc3FxRVVBUmNWZGdpbkhUc2IKdWVhc3NieUFZSGRJWGFiMjQvVzg0ZXpDYk8vMGhvcHhZZFhGVDYxQVc3R2RNL0IvNlYyU0hDWUFCd2FKU1dmNApZWHFpajJoMndUNDdYZHZscHNzQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZLWlJpc2FLS1c4YjFFcUlHeHhTcTkrdUdEWFNNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRjhHSjI1c1RqVEd3RDRoSDVmegp5bXU2WGhSd212ejBzemNKUTVKVVlsSndpUlJ0NUVBZ2lNUHZ0MndIeGt1UExGWDAwRFZ2MWorQkEzaEt5Wk5GClVaQUdrRmVwK0JyOWZYUWxVSE15OHZTZjFZSVhBRk43MFdBT0dFdVZjWEJDeDFNbWlBTndObUQyck1LdmFJK1cKci80Y1hMdXdVZlNUaUZaeFpaVGdaRkFtSFJ0QnVvSmpoaStmQjRPT2xTRFNEMU9PaFZjVVc3bWo3YkhJUjN1cgpzRnFYakp5eEc0T0JadlM5MTBXMUNtYTJWUTFCYnprY1h0YzJZOUdDSS9Cd3h2a0labWFSYy9ETFY1M0YxSmxXCnluNmovZEpvdmd6SGZqaVhheUxoekpaUDhMaG9ULzFacFQ2K214Uml0SHVMM2RVRW9oL2ttSzZqclBjZlFUWlMKTnRrPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    server: [https://10.1.8.30:6443](https://10.1.8.30:6443)
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURJVENDQWdtZ0F3SUJBZ0lJYm9pOWR1alB4dEF3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TWpBME1ESXdOVEEyTURWYUZ3MHlNekEwTURJd05UQTJNRGRhTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXhSbWh6MkpjWG83RmNIb1QKQ0d6dHkyRGplM1FvYVl1djVMMmV2V3NpMk14SmZRLzVnRWg4cDdXZEdTQ0NDL0t5a2Fvbk9ZWFh3MkxEVi9yVQpkbEtNbUtTN2s1eG5WWWV1M0EyZGlCMTU1MVVFK0lTelVPTE54c3J0MjdVajRuMDliUU5kSzhjeEZvclhxVUV0ClppVTdHY0dOZ3hRUVA4MkhGSDdTb09RTXRtTmo0bXdMWHVZbEFWODZ5TXl5RThQYjF5Y0FoQjhVY1BFUmRUeWQKeEtUY3FVbG0xYnQ4cU1CRzlYWUZFNk1IUUpldXk0Rnk3NjlYL2ZJNk9SZCtuUGdVWHVVd0FUYVdYR2JIeWhoUApDS0dKWXdzY09PRUFmWnRWV3RYUkxiM1pEWWpiVmFqTzllT0ZHYnorcjRxVDR2NEpkL1dZZ1RLcmUvTDBzVlhRCkROZWZDd0lEQVFBQm8xWXdWREFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RBWURWUjBUQVFIL0JBSXdBREFmQmdOVkhTTUVHREFXZ0JTbVVZckdpaWx2RzlSS2lCc2NVcXZmcmhnMQowakFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBckt4cjhFbEtYN2FYWUMvdzZhUFg4M3JvRHl0Q0NudTBTMHpWCm5WTVFnMUsvUmhRSGV5TnY2SGtycTJXSFhoUjh1L2M3Ukw3WGwyeDlzcWhPWmR3cGRrUlBXK0RENEs4TFMwYjAKUnhwdGxraW44UFE5QkZEOExuNDlmdmNhRG9LT0lhV2djZFFVMFRKQVZoZ1RNQ3FZZ0ZNTUhQa3I2d2Q2WVFtMgp3KzhsVlNCNytmeERKVlhkeUZWMFdOdk5Jb1JrM0FCcGEyOVVVZlZoY1FnZGI2M1RFamgwUlI0d014bjhhY2E1CnNiaE1wVmZiT2ZUU0pRTUJGRkRkMG5DWnJSN3NxQWluOUE2M3RydWZLTzJMTEF0YUVJeDRMUzJWZ09veG5odWEKQlh6UGp4SHF5TTR1WFRqQVlOMk44K2wxWXRBeSs0VTg2ZzVEMEZZeUpSTE5NMU5VL2c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBeFJtaHoySmNYbzdGY0hvVENHenR5MkRqZTNRb2FZdXY1TDJldldzaTJNeEpmUS81CmdFaDhwN1dkR1NDQ0MvS3lrYW9uT1lYWHcyTERWL3JVZGxLTW1LUzdrNXhuVllldTNBMmRpQjE1NTFVRStJU3oKVU9MTnhzcnQyN1VqNG4wOWJRTmRLOGN4Rm9yWHFVRXRaaVU3R2NHTmd4UVFQODJIRkg3U29PUU10bU5qNG13TApYdVlsQVY4NnlNeXlFOFBiMXljQWhCOFVjUEVSZFR5ZHhLVGNxVWxtMWJ0OHFNQkc5WFlGRTZNSFFKZXV5NEZ5Cjc2OVgvZkk2T1JkK25QZ1VYdVV3QVRhV1hHYkh5aGhQQ0tHSll3c2NPT0VBZlp0Vld0WFJMYjNaRFlqYlZhak8KOWVPRkdieityNHFUNHY0SmQvV1lnVEtyZS9MMHNWWFFETmVmQ3dJREFRQUJBb0lCQUNkS0hMOUNWRGRsTG1abApielhXd1BBeHVDYjcyTEp4YmZhaTllbThXWTN0NnhoSy91bGJpYjNFcmpROERyQmpDTVdRclpFQjVTakZuenNDCmZTZTQvTjNRdUxPTUVlMHl4dUNHdGtoVDErRU5TWmhnbTM0Y04valFxdW1KQ2tZendQTGlJTWlCUkgvQjNZdVgKdW4wS0h1WGJkMklSdGN1Q0pOTXBGTU9Oc2hzSkMyRTI1cmhXazlZZFdKTVVQV2JjMGZUd0RDdHhVSXpRNWhycApOa0tGenpBekdiVFA2dXA2dWJrYzQ4Zm9BNDVTRUJLNkhhcFZBNEQ1NzNQNFNmZWRodmhMVG9lbmQzM3NmeTJYCjlkS1dFOUg4VUQ3VGFRc3N6MG8xSU1xK0xVVU5UNUVqRkVCOXVtemIxTHB4YW1wUFJqVVpXU2ZEcXJDbGlvMkUKWHFaWkd3RUNnWUVBMm5Tbmd2R0p2NUZhdFVQeGppbWMyNHhOWjZSTWhRRFc3OG9TRUYrUUVoV2RscGlwTk94QQpVNTJNY1NrSmNMR1Jkd3VIaWdjQXVWVW90N09sak9MU1Zzak4yN0xRQTFraTNXbjYxeWVKUSs5MVpZMW9GaUJQCmpBZWJoS1BJanFPT2p3YUsrMEJ5cGFJb2dTb215dzErNklrSE5kNmJkc2FQbG1aMU9wc0hjRHNDZ1lFQTV2bG0KOGNvUUlEWWx5Q0x3YzMzSWRHd0xsWU9KUmFNdCs5QXRNY1VaZGZZN2gvaUlWTE4wSEZkUUFkOWxLUUxyNlpZVApuS0lWcUdzU1BiM2kyMCsyZHNVN3VPUjNOVkZCeHcvZUVVM1FnTjFtVTRnZzBLNnpORUpkKzZaYVo2cUQyVVhRCnY3cTdiOHhzekJoUkNMakdjb1huL2ZnWFBIWmRDUE9VVUVIWTczRUNnWUVBek1RSHVDK2JoSnRFd1IvY3JmckgKY3V1Q0txSFFyK0xubFlCOWlpZHBMZXBnK3FaQ0JMOW1WSG9iQ0g4RXdFTlJMSnI4QXg4cFNJOVFTVkQwM3FoRgpyTjh3UnJ6SFNqd2srQkc4OUN1MCtKN2VGY0NFVGlrZkp3eUNjOFBwMi9ublNKMURiTnN1RzU5eUJCQjBxR1FRCkR2dFNiT1lxSngxYnZnaHYzZTB1L2IwQ2dZRUF4NHc1TURQT2NzWFZKbTlwSlo1S0RLczc1dFJaU0Z5T1lidWQKRUI2a3ZKRWJKWUhHNXNhVFRkanhPbXp5VE5oRlVPMWp6RE1NV3hFR0ZXbDBFTjF4V25OVUFZMEFvSU92UEhlcwo5MjR1OE9aV2ZWeGlYV2hSVXBqejhYSHJNUnpVQkdhWXpzeFpHMkdWclU1azFCQXZBc3BGZjlsUzJkMjR5djhGCjU4QzcxMEVDZ1lBV0p4NmpuV05vbGc1QzhvSGpDT0Jkb0RGdHhGeEpiT2M5QUJ2aHpZbGlTSHp5aTY3RjVQZ28KREdaWXJjWWZxYVY5MVl5R24xaWQybG5GcVZoZ1VGYnpGS2t4U0FaS0FJVDRwbGNucVRWQm9oc1UwMkxqSUdEZwpESU5SQW8xb0dqRTdOM3FWUVFzS0huSDBnUXNwWVZpN3NFRzRDdWtZSDQ2MUNCM0dET0N0b3c9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=

说明:

  • certificate-authority-data 指定CA证书,通过base64编码。
yaml 复制代码
# base64解码ca证书字符串,输出原始证书内容
root@master30:~# echo LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURJVENDQWdtZ0F3SUJBZ0lJYm9pOWR1alB4dEF3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TWpBME1ESXdOVEEyTURWYUZ3MHlNekEwTURJd05UQTJNRGRhTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXhSbWh6MkpjWG83RmNIb1QKQ0d6dHkyRGplM1FvYVl1djVMMmV2V3NpMk14SmZRLzVnRWg4cDdXZEdTQ0NDL0t5a2Fvbk9ZWFh3MkxEVi9yVQpkbEtNbUtTN2s1eG5WWWV1M0EyZGlCMTU1MVVFK0lTelVPTE54c3J0MjdVajRuMDliUU5kSzhjeEZvclhxVUV0ClppVTdHY0dOZ3hRUVA4MkhGSDdTb09RTXRtTmo0bXdMWHVZbEFWODZ5TXl5RThQYjF5Y0FoQjhVY1BFUmRUeWQKeEtUY3FVbG0xYnQ4cU1CRzlYWUZFNk1IUUpldXk0Rnk3NjlYL2ZJNk9SZCtuUGdVWHVVd0FUYVdYR2JIeWhoUApDS0dKWXdzY09PRUFmWnRWV3RYUkxiM1pEWWpiVmFqTzllT0ZHYnorcjRxVDR2NEpkL1dZZ1RLcmUvTDBzVlhRCkROZWZDd0lEQVFBQm8xWXdWREFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RBWURWUjBUQVFIL0JBSXdBREFmQmdOVkhTTUVHREFXZ0JTbVVZckdpaWx2RzlSS2lCc2NVcXZmcmhnMQowakFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBckt4cjhFbEtYN2FYWUMvdzZhUFg4M3JvRHl0Q0NudTBTMHpWCm5WTVFnMUsvUmhRSGV5TnY2SGtycTJXSFhoUjh1L2M3Ukw3WGwyeDlzcWhPWmR3cGRrUlBXK0RENEs4TFMwYjAKUnhwdGxraW44UFE5QkZEOExuNDlmdmNhRG9LT0lhV2djZFFVMFRKQVZoZ1RNQ3FZZ0ZNTUhQa3I2d2Q2WVFtMgp3KzhsVlNCNytmeERKVlhkeUZWMFdOdk5Jb1JrM0FCcGEyOVVVZlZoY1FnZGI2M1RFamgwUlI0d014bjhhY2E1CnNiaE1wVmZiT2ZUU0pRTUJGRkRkMG5DWnJSN3NxQWluOUE2M3RydWZLTzJMTEF0YUVJeDRMUzJWZ09veG5odWEKQlh6UGp4SHF5TTR1WFRqQVlOMk44K2wxWXRBeSs0VTg2ZzVEMEZZeUpSTE5NMU5VL2c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== | base64 -d
-----BEGIN CERTIFICATE-----
MIIDITCCAgmgAwIBAgIIboi9dujPxtAwDQYJKoZIhvcNAQELBQAwFTETMBEGA1UE
AxMKa3ViZXJuZXRlczAeFw0yMjA0MDIwNTA2MDVaFw0yMzA0MDIwNTA2MDdaMDQx
FzAVBgNVBAoTDnN5c3RlbTptYXN0ZXJzMRkwFwYDVQQDExBrdWJlcm5ldGVzLWFk
bWluMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxRmhz2JcXo7FcHoT
CGzty2Dje3QoaYuv5L2evWsi2MxJfQ/5gEh8p7WdGSCCC/KykaonOYXXw2LDV/rU
dlKMmKS7k5xnVYeu3A2diB1551UE+ISzUOLNxsrt27Uj4n09bQNdK8cxForXqUEt
ZiU7GcGNgxQQP82HFH7SoOQMtmNj4mwLXuYlAV86yMyyE8Pb1ycAhB8UcPERdTyd
xKTcqUlm1bt8qMBG9XYFE6MHQJeuy4Fy769X/fI6ORd+nPgUXuUwATaWXGbHyhhP
CKGJYwscOOEAfZtVWtXRLb3ZDYjbVajO9eOFGbz+r4qT4v4Jd/WYgTKre/L0sVXQ
DNefCwIDAQABo1YwVDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH
AwIwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSmUYrGiilvG9RKiBscUqvfrhg1
0jANBgkqhkiG9w0BAQsFAAOCAQEArKxr8ElKX7aXYC/w6aPX83roDytCCnu0S0zV
nVMQg1K/RhQHeyNv6Hkrq2WHXhR8u/c7RL7Xl2x9sqhOZdwpdkRPW+DD4K8LS0b0
Rxptlkin8PQ9BFD8Ln49fvcaDoKOIaWgcdQU0TJAVhgTMCqYgFMMHPkr6wd6YQm2
w+8lVSB7+fxDJVXdyFV0WNvNIoRk3ABpa29UUfVhcQgdb63TEjh0RR4wMxn8aca5
sbhMpVfbOfTSJQMBFFDd0nCZrR7sqAin9A63trufKO2LLAtaEIx4LS2VgOoxnhua
BXzPjxHqyM4uXTjAYN2N8+l1YtAy+4U86g5D0FYyJRLNM1NU/g==
-----END CERTIFICATE-----
  • client-certificate-data 指定用户证书,同样是 base64 编码。
  • client-key-data 指定用户私钥,同样是 base64 编码。
多集群配置

示例:/root/multi-cluster-config

yaml 复制代码
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED # 集群1ca证书
    server: [https://10.1.8.30:6443](https://10.1.8.30:6443) # 集群1apiserver地址
  name: cluster1 # 集群1名称
- cluster:
    certificate-authority-data: DATA+OMITTED # 集群2ca证书
    server: [https://10.1.8.150:6443](https://10.1.8.150:6443) # 集群2apiserver地址
  name: cluster2 # 集群2名称
contexts:
- context:
    cluster: cluster1 # 关联集群1
    namespace: default # 默认命名空间
    user: cluster1-admin # 关联集群1用户
  name: cluster1-context # 上下文1名称
- context:
    cluster: cluster2 # 关联集群2
    namespace: default # 默认命名空间
    user: cluster2-admin # 关联集群2用户
  name: cluster2-context # 上下文2名称
current-context: cluster1-context # 当前激活上下文
kind: Config
preferences: {}
users:
- name: cluster1-admin # 集群1用户
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED
- name: cluster2-admin # 集群2用户
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED

配置文件定义了以下资源:

  • clusters:集群信息,包括集群名、authority、地址和端口。
  • users:用户信息,包括用户名、certificate和key。
  • contexts:上下文信息,包括上下文名称、集群名、用户名和namespace。

多集群切换

kubernetes 自带工具

环境准备:

bash 复制代码
# 备份原有kubeconfig配置
root@master30:~# cp .kube/config .kube/config.ori

# 将多集群配置覆盖到kubeconfig
root@master30:~# cp multi-cluster-config .kube/config

查看集群清单

bash 复制代码
# 获取配置文件中定义的全部集群名称
root@master30:~# kubectl config get-clusters
NAME
cluster1
cluster2

查看上下文清单

bash 复制代码
# 查看所有上下文,*代表当前激活上下文
root@master30:~# kubectl config get-contexts
CURRENT   NAME               CLUSTER    AUTHINFO         NAMESPACE
*         cluster1-context   cluster1   cluster1-admin   default
          cluster2-context   cluster2   cluster2-admin   default

* 代表当前使用的上下文

切换上下文

bash 复制代码
# 切换到cluster2-context上下文,访问第二个集群
root@master30:~# kubectl config use-context cluster2-context

# 确认上下文切换完成
root@master30:~# kubectl config get-contexts
CURRENT   NAME               CLUSTER    AUTHINFO         NAMESPACE
          cluster1-context   cluster1   cluster1-admin   default
*         cluster2-context   cluster2   cluster2-admin   default
kubectx-第三方工具

kubectx 安装

bash 复制代码
# 下载kubectx工具源码包
root@master30:~# wget [https://codeload.github.com/ahmetb/kubectx/zip/refs/heads/master](https://codeload.github.com/ahmetb/kubectx/zip/refs/heads/master) -O kubectx.zip

# 解压源码包
root@master30:~# unzip kubectx.zip

# 查看解压目录文件
root@master30:~# ls kubectx-master/
CONTRIBUTING.md  README.md  completion  go.sum  internal  kubens
LICENSE          cmd        go.mod      img     kubectx   test

# 将kubectx二进制复制到系统全局bin目录
root@master30:~# cp kubectx-master/kubectx /usr/local/bin/

# 添加执行权限
root@master30:~# chmod +x /usr/local/bin/kubectx

# 拷贝bash补全脚本
root@master30:~# cp kubectx-master/completion/kubectx.bash /etc/bash_completion.d/

# 加载补全脚本生效
root@master30:~# source /etc/bash_completion.d/kubectx.bash

kubectx 帮助

bash 复制代码
# 查看kubectx帮助信息
root@master30:~# kubectx -h
USAGE:
  kubectx                       : list the contexts
  kubectx <NAME>                : switch to context <NAME>
  kubectx -                     : switch to the previous context
  kubectx -c, --current         : show the current context name
  kubectx <NEW_NAME>=<NAME>     : rename context <NAME> to <NEW_NAME>
  kubectx <NEW_NAME>=.          : rename current-context to <NEW_NAME>
  kubectx -d <NAME> [<NAME...>] : delete context <NAME> ('.' for current-context)
                                  (this command won't delete the user/cluster entry
                                  that is used by the context)
  kubectx -u, --unset           : unset the current context
  kubectx -h,--help             : show this message

kubectx 命令使用

bash 复制代码
# 列出全部上下文
root@master30:~# kubectx
cluster1-context
cluster2-context

# 打印当前正在使用的上下文名称
root@master30:~# kubectx -c
cluster2-context

# 切换上下文到cluster1-context
root@master30:~# kubectx cluster1-context
Switched to context "cluster1-context".

# 再次查看当前上下文
root@master30:~# kubectx -c
cluster1-context

# 取消当前上下文设置
root@master30:~# kubectx -u
Unsetting current context.
Property "current-context" unset.

# 获取当前上下文,无上下文时报错
root@master30:~# kubectx -c
error: current-context is not set

Kubernetes Pod

学习参考:Pod

环境准备

bash 复制代码
# 创建pods命名空间
root@master30:~# kubectl create ns pods

# 设置当前上下文默认namespace为pods,后续操作不用加-n
root@master30:~# kubectl config set-context --current --namespace pods

Pod 介绍

pod 代表一个deployment单元:a single instance of an application in Kubernetes。 k8s通过定义一个Pod的资源,然后在Pod里面运行容器,容器需要指定镜像,用来运行具体的服务。Pod代表集群上正在运行的一个进程,一个Pod封装一个容器(也可以封装多个容器),Pod里的容器共享存储、网络等。也就是说,应该把整个pod看作虚拟机,然后每个容器相当于运行在虚拟机的进程。

  • 运行单个容器的 Pod:将Pod看作是单个容器的包装器,kubernetes管理pods而不是直接管理容器。
  • 运行多个容器的 Pod :POD可以封装一个由多个共存容器组成的应用程序。pod中的容器会自动在集群中的同一物理机或虚拟机上运行。POD中多个容器共享资源和依赖项,彼此通信,以及协调何时以及如何终止它们。POD将这些容器、网络资源和存储资源作为一个单一的可管理实体包装在一起。pod中多个容器共享网络和存储资源。每个pod分配唯一的ip地址,pod中容器共享netns,包括ip地址和port端口。多个容器之间使用localhost通信。当pod中容器与其他pod通信,需要使用共享的网络资源。pod可以使用多个volume,pod中所有容器都可以访问这些卷。

白话解释: 可以把pod看成是一个"豌豆荚",里面有很多"豆子"(容器)。一个豌豆荚里的豆子,它们吸收着共同的营养成分、肥料、水分等,Pod和容器的关系也是一样,Pod里面的容器共享pod的网络、存储等。

例如:web容器提供文件共享,另外一个容器负责更新文件内容。

pod 基本管理

创建 pod

复制代码
# --dry-run=client 只输出yaml,不真正创建pod;-o yaml输出yaml格式
root@master30:~# kubectl run web --image=hub.laodi.cloud/library/nginx --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: web
  name: web
spec:
  containers:
  - image: hub.laodi.cloud/library/nginx
    name: web
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
# 直接创建运行pod
root@master30:~# kubectl run web --image=hub.laodi.cloud/library/nginx
pod/web created

# 查看pod状态,刚创建是ContainerCreating拉取镜像启动
root@master30:~# kubectl get pod
NAME   READY   STATUS              RESTARTS   AGE
web    0/1     ContainerCreating   0          36s

# 再次查看pod状态,变为Running正常运行
root@master30:~# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
web    1/1     Running   0          51s

# -o wide 查看pod所在节点、podIP等扩展信息
root@master30:~# kubectl get pod -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP              NODE               NOMINATED NODE   READINESS GATES
web    1/1     Running   0          67s   10.224.51.131   worker31.laodi.cloud   <none>           <none>

# ssh登录pod所在worker节点,使用nerdctl查看k8s.io命名空间下容器,过滤web
root@master30:~# ssh root@worker31 nerdctl ps --namespace k8s.io |grep web

# 在worker节点查看本地镜像,过滤nginx
root@master30:~# ssh root@worker31 nerdctl images --namespace k8s.io |grep nginx

查看 pod

复制代码
# 获取pod资源yaml完整定义
root@master30:~# kubectl get pod web -o yaml

# describe查看pod详细事件、状态、事件日志
root@master30:~# kubectl describe pod web

# 查看pod容器标准输出日志,-f持续跟踪日志输出
root@master30:~# kubectl logs -f web 

编辑 pod

复制代码
# 在线编辑pod资源,部分字段不支持热更新
root@master30:~# kubectl edit pod web

提示:并不是所有属性都可以编辑,例如pod名称。如果非要编辑特定属性,可以先删除pod,然后修改pod对的yaml文件,重新创建。

pod 中执行命令

复制代码
# 在pod容器内执行hostname命令
root@master30:~# kubectl exec web -- hostname
web

# 在pod容器执行pwd命令
root@master30:~# kubectl exec web -- pwd
/

# -it交互式,在pod容器执行shell命令,覆盖页面文件
root@master30:~# kubectl exec -it web -- bash -c 'echo Hello World > htdocs/index.html'

# 在pod容器执行id查看用户id
root@master30:~# kubectl exec web -- id
uid=0(root) gid=0(root) groups=0(root)

cp 文件给 pod

复制代码
# 将宿主机/etc/hosts拷贝到pod内/new-hosts
root@master30:~# kubectl cp /etc/hosts web:/new-hosts

# 在pod中验证文件是否拷贝成功
root@master30:~# kubectl exec web -- ls /new-hosts
/new-hosts

删除 pod

复制代码
# 删除pod资源
root@master30:~# kubectl delete pod web
pod "web" deleted

删除时间

复制代码
# 查看pod优雅终止超时时间,默认30秒
root@master30:~# kubectl get pod web -o yaml|grep ' terminationGracePeriodSeconds'
terminationGracePeriodSeconds: 30

yaml 文件创建 pod

复制代码
# web.yaml pod资源定义yaml文件
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: web
  name: web
spec:
  containers:
  - image: hub.laodi.cloud/library/nginx
    name: web
# 通过yaml创建pod
root@master30:~# kubectl create -f web.yaml
# 或者apply,支持创建+更新
root@master30:~# kubectl apply -f web.yaml

综合实验:构建 wordpreess

  1. 创建 pod-mysql 数据库

  2. 创建 pod-wordpress 博客 参考步骤:

    创建mysql pod,设置root密码环境变量

    root@master30:~# kubectl run wordpress-db --image=hub.laodi.cloud/library/mysql --env MYSQL_ROOT_PASSWORD=123

    创建wordpress应用pod

    root@master30:~# kubectl run wordpress-app --image=hub.laodi.cloud/library/wordpress

    port-forward端口转发,宿主机10.1.8.30:8080转发到pod的80端口,用于外部访问pod

    root@master30:~# kubectl port-forward pod/wordpress-app --address 10.1.8.30 8080:80

    该命令窗口不要关闭

    获取pod名称和podIP

    root@master30:~# kubectl get pods -o wide | awk '{print 1" "6}'
    NAME IP
    wordpress-app 10.224.113.135
    wordpress-db 10.224.19.5

    使用mysql客户端连接pod内mysql,初始化数据库与账号

    root@master30:~# mysql -uroot -p123 -h 10.224.19.5
    mysql> create database wordpress;
    mysql> create user wordpress identified by '123';
    mysql> grant all privileges on wordpress.* to wordpress;
    mysql> flush privileges;
    mysql> exit

访问web页面 http://10.1.8.30:8080,配置站点。

多容器 pod

示例文件:blog.yaml

复制代码
# 编辑多容器pod yaml
root@master30:~# vim pod-blog.yaml
apiVersion: v1
kind: Pod
metadata:
  name: bbs
  labels:
    run: bbs
spec:
  containers:
  # 第一个容器 mysql数据库
  - image: hub.laodi.cloud/library/mysql:latest
    imagePullPolicy: IfNotPresent # 本地有镜像优先用本地
    name: mysql
    env: # 环境变量配置
    - name: MYSQL_ROOT_PASSWORD
      value: "123"
    - name: MYSQL_USER
      value: tom
    - name: MYSQL_PASSWORD
      value: "123"
    - name: MYSQL_DATABASE
      value: bbs
    ports:
    - containerPort: 3306 # 容器内部端口
      name: mysql
      protocol: TCP
  # 第二个容器 wordpress博客
  - image: hub.laodi.cloud/library/wordpress:latest
    imagePullPolicy: IfNotPresent
    name: wordpress
    env:
    - name: WORDPRESS_DB_USER
      value: tom
    - name: WORDPRESS_DB_PASSWORD
      value: "123"
    - name: WORDPRESS_DB_NAME
      value: bbs
    - name: WORDPRESS_DB_HOST
      value: 127.0.0.1 # pod内部localhost互通,共享net namespace
    ports:
    - containerPort: 80
      name: wordpress
      protocol: TCP
      hostPort: 80 # 占用宿主机80端口
# 应用yaml创建多容器pod
root@master30:~# kubectl apply -f pod-blog.yaml

# -o wide查看pod运行在哪台节点
root@master30:~# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP              NODE               NOMINATED NODE   READINESS GATES
bbs    2/2     Running   0          10m   10.224.225.68   worker32.laodi.cloud   <none>           <none>

# 多容器pod,-c指定容器名称,在wordpress容器执行hostname
root@master30:~# kubectl exec bbs -c wordpress -- hostname
bbs

# cp文件,指定拷贝到wordpress容器
root@master30:~# kubectl cp /etc/hosts bbs:/new-hosts -c wordpress

# 在wordpress容器验证文件
root@master30:~# kubectl exec bbs -c wordpress -- ls /new-hosts
/new-hosts

数据库访问测试

复制代码
# 指定mysql容器,执行mysql命令查看数据库
root@master30:~# kubectl exec bbs -c mysql -it -- mysql -utom -p123 -e 'show databases;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database           |
+--------------------+
| bbs                |
| information_schema |
| performance_schema |

使用所在宿主机的80端口访问:http://10.1.8.32/

pod 关键属性

复制代码
# 使用explain查看pod顶层字段说明
root@master30:~# kubectl explain pod | grep '^  [a-zA-Z]'
  apiVersion	<string>
  kind	<string>
  metadata	<ObjectMeta>
  spec	<PodSpec>
  status	<PodStatus>

pod.metadata

复制代码
# explain查看pod metadata子字段
root@master30:~# kubectl explain pod.metadata | grep '^  [a-zA-Z]'
   annotations	<map[string]string>
   clusterName	<string>
   creationTimestamp	<string>
   deletionGracePeriodSeconds	<integer>
   deletionTimestamp	<string>
   finalizers	<[]string>
   generateName	<string>
   generation	<integer>
   labels	<map[string]string>
   managedFields	<[]Object>
   name	<string>
   namespace	<string>
   ownerReferences	<[]Object>
   resourceVersion	<string>
   selfLink	<string>
   uid	<string>

需要关注的属性:labels,name,namespace。

pod.spec

复制代码
# explain查看pod.spec字段
root@master30:~# kubectl explain pod.spec | grep '^  [a-zA-Z]'
   activeDeadlineSeconds	<integer>
   affinity	<Object>
   automountServiceAccountToken	<boolean>
   containers	<[]Object> -required-
   dnsConfig	<Object>
   dnsPolicy	<string>
   enableServiceLinks	<boolean>
   ephemeralContainers	<[]Object>
   hostAliases	<Object>
   hostIPC	<boolean>
   hostNetwork	<boolean>
   hostPID	<boolean>
   hostname	<string>
   imagePullSecrets	<[]Object>
   initContainers	<[]Object>
   nodeName	<string>
   nodeSelector	<map[string]string>
   overhead	<map[string]string>
   preemptionPolicy	<string>
   priority	<integer>
   priorityClassName	<string>
   readinessGates	<[]Object>
   restartPolicy	<string>
   runtimeClassName	<string>
   schedulerName	<string>
   securityContext	<Object>
   serviceAccount	<string>
   serviceAccountName	<string>
   setHostnameAsFQDN	<boolean>
   shareProcessNamespace	<boolean>
   subdomain	<string>
   terminationGracePeriodSeconds	<integer>
   tolerations	<[]Object>
   topologySpreadConstraints	<[]Object>
   volumes	<[]Object>

重点关注:containers、nodeName、volumes等。

pod.spec.containers
复制代码
# explain查看containers内部字段
root@master30:~# kubectl explain pod.spec.containers | grep '^   [a-zA-Z]'
   args	<[]string>
   command	<[]string>
   env	<[]Object>
   envFrom	<[]Object>
   image	<string>
   imagePullPolicy	<string>
   lifecycle	<Object>
   livenessProbe	<Object>
   name	<string> -required-
   ports	<Object>
   readinessProbe	<Object>
   resources	<Object>
   securityContext	<Object>
   startupProbe	<Object>
   stdin	<boolean>
   stdinOnce	<boolean>
   terminationMessagePath	<string>
   terminationMessagePolicy	<string>
   tty	<boolean>
   volumeDevices	<[]Object>
   volumeMounts	<[]Object>
   workingDir	<string>

重点关注:command、env、image、imagePullPolicy、volumeMounts等。

pod.spec.containers.ImagePullPolicy
  • Always,总是从仓库下载镜像。
  • Never,只使用本地镜像,不下载。
  • IfNotPresent,优先使用本地镜像,如果没有才从仓库下载镜像。
pod lifecycle 和 status
pod lifecycle
  • pod的生命周期取决于pod中所有容器的生命周期。
  • 容器的生命周期取决于容器中进程的生命周期。
Pod status

常见 pod 状态如下:

  • ContainerCreating 正在创建
  • Running 正在运行
  • Completed 运行完成
  • Error/RunContainerError 运行错误
  • CrashLoopBackOff 重新创建
  • ErrImagePull 获取镜像错误
  • ImagePullBackOff 重新获取镜像
  • Terminating,正在终止(删除)

实验1:pod中包含1个容器,验证pod状态 监控命令: watch -n 1 kubectl get pod # 每秒刷新一次查看pod列表

示例1:

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: Never # 容器退出不重启
  containers:
  - name: busybox
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 10'] # 执行输出,休眠10秒后进程退出

command命令可以改写如下:

复制代码
command:
- sh
- -c
- echo OK! && sleep 10

或者

复制代码
args:
- sh
- -c
- echo OK! && sleep 10

观察pod状态为:ContainerCreating-->Running-->Completed

示例2:

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: Never
  containers:
  - name: busybox
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echoxxx Hello Kubernetes! && sleep 5'] # echoxxx是错误命令,执行直接报错退出

实验2:pod中包含2个容器,验证pod状态

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: Never
  containers:
  - name: busybox1
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 5'] # 5秒退出
  - name: busybox2
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 10'] #10秒退出

观察pod状态为:ContainerCreating-->Running-->NotReady-->Completed

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: Never
  containers:
  - name: busybox1
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echoxx Hello Kubernetes! && sleep 5'] #错误命令直接报错
  - name: busybox2
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 20']

观察pod状态为:ContainerCreating-->Error

pod.spec.restartPolicy

示例:

复制代码
  restartPolicy: Never # 重启策略,容器退出不重启
  containers:
  - name: myapp-container
    image: hub.laodi.cloud/library/busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 5'] 

restartPolicy,针对pod中所有容器生效。

  • Always,除了 Running 状态,其他状态总是重启,默认值。
  • OnFailure,失败了才重启。
  • Never,从不重启。

实验1:验证pod中含有单个容器重启策略。 更改pod重启策略,直接apply会报错,需要删除重建。

第一个yaml验证Always/OnFailure/Never重启策略

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: Always/OnFailure/Never # 修改此处切换策略
  containers:
  - name: busybox
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 5']

第二个yaml验证OnFailure

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: OnFailure
  containers:
  - name: busybox
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echoxxx Hello Kubernetes! && sleep 5'] #错误命令,进程异常退出

第三个yaml验证 Never 重启策略

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: Never
  containers:
  - name: busybox
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echoxxx Hello Kubernetes! && sleep 5']

实验2:验证pod中含有多个容器重启策略。 验证结果:只要有一个容器满足重启策略条件,就会重启。

示例1:

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: Always/OnFailure/Never
  containers:
  - name: busybox1
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 5']
  - name: busybox2
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 5']

使用Always重启策略时,当容器busybox1状态为Completed时,容器busybox2还未创建成功,此时会根据重启策略重启pod。当然也可以将容器的生命周期延长,sleep 5改为sleep 50,运行50s之后还会重启pod。 使用OnFailure/Never重启策略就不会出现这种情况。

示例2:第二个command是错误的。

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: Always/OnFailure/Never
  containers:
  - name: busybox1
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 5']
  - name: busybox2
    image: hub.laodi.cloud/library/busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echoxxx Hello Kubernetes! && sleep 5'] #错误命令,执行异常

Always和OnFailure重启策略总是会重启pod;Never重启策略就不会重启pod。

Init Containers

initContainers 是 Pod 中优先于业务容器执行的特殊容器列表 。 一个pod可以有多个容器在其中运行应用程序,也可以有一个或多个initContainers。 所有 init 容器按顺序串行执行 ,全部成功退出(exit 0)之后,才会启动 Pod 里普通业务 containers; 只要任意一个 initContainer 失败退出,kubernetes根据restartpolicy重启pod,直到全部 init容器 执行成功。

使用场景: 1、等待某个服务创建成功。

复制代码
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1

2、等待固定时间后再运行app容器。

复制代码
sleep 60

3、Clone a git repository into a volume

示例1:

复制代码
# 编辑pod yaml文件
root@master30:~/pods# vim pod-myapp.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  volumes:
  - name: workdir
    emptyDir: {} # emptyDir临时卷,pod生命周期内有效
  containers:
  - name: myapp-container
    image: hub.laodi.cloud/library/busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
    volumeMounts:
    - name: workdir # 挂载上面定义的workdir卷
      mountPath: "/work-dir"
  initContainers: #初始化容器,优先执行
  - name: init-poda
    image: hub.laodi.cloud/library/busybox
    command: ['sh', '-c', 'touch /work-dir/aa.txt && sleep 10'] #初始化阶段创建文件
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"

在app容器中查看文件

复制代码
# 在业务容器查看/work-dir目录文件
root@master30:~# kubectl exec myapp-pod -c myapp-container -- ls /xx

pod的状态变化:Init:0/1->PodInitializing->Running

将初始化容器command变更为以下内容再测试:

复制代码
command: ['sh', '-c', 'touchxx /work-dir/aa.txt'] # touchxx不存在,命令报错

pod的状态变化: Init:0/1->Init:Error->Init:CrashLoopBackOff,然后Init:Error->Init:CrashLoopBackOff循环。

示例2:

复制代码
# 编辑资源yaml
root@master30:~# vim pod-myapp.yaml
# myservice service资源定义
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
# mydb service资源定义
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377
# myapp pod资源定义
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  initContainers:
  - name: init-myservice
    image: hub.laodi.cloud/library/busybox
    # 注意service 完整名称,循环dns解析等待myservice服务就绪
    command: ['sh', '-c', 'until nslookup myservice.webapp.svc.cluster.local; do echo waiting for myservice; sleep 2;
touch /work-dir/aa.txt && sleep 10'] #初始化阶段创建文件
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"

在app容器中查看文件

复制代码
# 在业务容器查看/work-dir目录文件
root@master30:~# kubectl exec myapp-pod -c myapp-container -- ls /xx

pod的状态变化:Init:0/1->PodInitializing->Running

将初始化容器command变更为以下内容再测试:

复制代码
command: ['sh', '-c', 'touchxx /work-dir/aa.txt'] # touchxx不存在,命令报错

pod的状态变化: Init:0/1->Init:Error->Init:CrashLoopBackOff,然后Init:Error->Init:CrashLoopBackOff循环。

示例2:

复制代码
# 编辑资源yaml
root@master30:~# vim pod-myapp.yaml
# myservice service资源定义
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
# mydb service资源定义
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377
# myapp pod资源定义
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  initContainers:
  - name: init-myservice
    image: hub.laodi.cloud/library/busybox
    # 注意service 完整名称,循环dns解析等待myservice服务就绪
    command: ['sh', '-c', 'until nslookup myservice.webapp.svc.cluster.local; do echo waiting for myservice; sleep 2;
相关推荐
艾iYYY2 小时前
【无标题】
linux·开发语言·网络·操作系统
阿里云云原生2 小时前
从单点探索到规模化运营:滔搏体育的企业级多智能体实践
云原生
QZ166560951592 小时前
可视化易用·低误报率·跨区域部署:知源-AI数据分类分级系统在金融行业的落地实践
大数据·网络·安全·网络安全
aixingkong9212 小时前
UALink 技术白皮书解读
服务器·网络·硬件架构
mklpo1472 小时前
在 安卓手机 上通过termux运行 gentoo 和 宝塔面板。2026.10.19
linux·运维·服务器
flytalei2 小时前
从 Docker Compose 到 K3s:逐浪博客 MySQL 数据迁移实战与一致性验证
mysql·docker·容器
周周爱喝粥呀2 小时前
详细教程:在 Docker 中部署 PostgreSQL 并使用 pgAdmin 可视化管理
docker·postgresql·容器
xatu3 小时前
ubuntu容器在redhat系统下使用大模型API问题
linux·运维·ubuntu
Amumu121383 小时前
Node学习: 网络基础概念 + HTTP模块
网络·node.js