Kubernetes 访问 Dashboard
tags: Dashboard
文章目录
Kubernetes 访问 Dashboard
1. 简介
2. 默认 dashboard 权限
3. 验证
3.1 登录视图
3.2 Authorization header
3.3 Bearer Token
3.4 默认
3.5 Kubeconfig
4. 管理员权限
5. Dashboard 参数
6 访问
6.1 NodePort 访问
6.2 kubeconfig 访问
6.3 proxy 访问
1. 简介
Dashboard 是基于网页的 Kubernetes 用户界面。 你可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群资源。 你可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源 (如 Deployment,Job,DaemonSet 等等)。 例如,你可以对 Deployment 实现弹性伸缩、发起滚动升级、重启 Pod 或者使用向导创建新的应用。
2. 默认 dashboard 权限
get,update以及命名空间中的delete Secrets的权限。kubernetes-dashboard-key-holder、kubernetes-dashboard-certs、kubernetes-dashboard-csrf、kubernetes-dashboard
get和命名空间中命名update的配置映射的权限。kubernetes-dashboard-settings、kubernetes-dashboard
get 权限services/proxy,以便允许收集指标所需的命名空间中的heapster服务dashboard-metrics-scraper。kubernetes-dashboard
get,list以及API 的watch权限,metrics.k8s.io以便允许从metrics-server访问dashboard-metrics-scraper.
3. 验证
Kubernetes Dashboard 支持几种不同的用户身份验证方式:
授权标头(Authorization header )在每个请求中传递给仪表板。从 1.6 版开始支持。具有最高优先级。如果存在,将跳过登录视图。
可在仪表板登录视图上使用的不记名令牌。
可在仪表板登录视图中使用的用户名/密码。
可用于 Dashboard登录视图的Kubeconfig文件。
3.1 登录视图
如果您使用的是推荐的最新安装,则默认情况下将启用登录功能。--tls-cert-file在任何其他情况下,如果您更喜欢手动配置证书,则需要将--tls-cert-key标志传递给 Dashboard。HTTPS 端点将暴露在Dashboard 容器的端口上8443。您可以通过提供--port标志来更改它。
使用Skip选项将使 Dashboard 使用 Dashboard 使用的 Service Account 的权限。Skip自 1.10.1 起,按钮默认禁用。使用–enable-skip-login仪表板标志来显示它。
3.2 Authorization header
通过 HTTP 访问 Dashboard 时,使用授权标头是使 Dashboard 充当用户的唯一方法。请注意,由于普通 HTTP 流量容易受到MITM 攻击,因此存在一些风险。
要使 Dashboard 使用授权标头,您只需将Authorization: Bearer <token>每个请求传递给 Dashboard。这可以通过在仪表板前面配置反向代理来实现。代理将负责与身份提供者进行身份验证,并将请求标头中生成的令牌传递给仪表板。请注意,Kubernetes API 服务器需要正确配置才能接受这些令牌。
要快速测试它,请查看允许手动修改请求标头的Requestly Chrome 浏览器插件。
重要提示:如果通过 API 服务器代理访问 Dashboard,授权标头将不起作用。访问仪表板指南中描述的访问仪表kubectl proxy板和访问仪表板的方式都将不起作用。这是因为一旦请求到达 API 服务器,所有额外的标头都会被丢弃。
3.3 Bearer Token
建议先熟悉Kubernetes认证文档,了解如何获取token,可以用来登录。例如,每个服务帐户都有一个带有有效承载令牌的秘密,可用于登录仪表板。
如何创建服务帐户并授予其权限:
Service Account Tokens
Role and ClusterRole
Service Account Permissions
3.4 默认
默认情况下禁用基本身份验证。原因是 Kubernetes API 服务器需要配置授权模式 ABAC 和--basic-auth-file提供的标志。如果没有该 API 服务器会自动回退到匿名用户,并且无法检查提供的凭据是否有效。
为了在仪表板--authentication-mode=basic标志中启用基本身份验证,必须提供。默认情况下,它设置为–authentication-mode=token。
注意:基本身份验证--basic-auth-file自 Kubernetes v1.19起已被弃用。对于要–basic-auth-file标记的类似功能,请--token-auth-file 与Static Token File一起使用。
3.5 Kubeconfig
提供这种登录方法是为了方便。 kubeconfig 文件中仅支持 flag 指定--authentication-mode
的身份验证选项。如果它被配置为使用任何其他方式,错误将显示在仪表板中。目前不支持外部身份提供者或基于证书的身份验证。
4. 管理员权限
您可以通过在下面创建来授予 Dashboard 的服务帐户完整的管理员权限ClusterRoleBinding。根据选择的安装方法复制 YAML 文件并另存为,即dashboard-admin.yaml. 用于kubectl create -f dashboard-admin.yaml部署它。之后,您可以使用Skip登录页面上的选项来访问仪表板。
正式发布
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard namespace: kubernetes-dashboard roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kubernetes-dashboard
开发版本
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard-head namespace: kubernetes-dashboard-head roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: kubernetes-dashboard-head namespace: kubernetes-dashboard-head
5. Dashboard 参数
参数列表:
6 访问
6.1 NodePort 访问
https://github.com/kubernetes/dashboard
$ wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.1.0/aio/deploy/recommended.yaml $ vim recommended.yaml //跳转到40行左右,修改其对应的service,类型配置为Nodeport kind: Service apiVersion: v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard spec: type: NodePort //添加类型为NodePort ports: - port: 443 targetPort: 8443 nodePort: 31010 //映射到宿主机的端口为31010 selector: k8s-app: kubernetes-dashboard $ kubectl apply -f recommended.yaml namespace/kubernetes-dashboard created serviceaccount/kubernetes-dashboard created service/kubernetes-dashboard created secret/kubernetes-dashboard-certs created secret/kubernetes-dashboard-csrf created secret/kubernetes-dashboard-key-holder created configmap/kubernetes-dashboard-settings created role.rbac.authorization.k8s.io/kubernetes-dashboard created clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created deployment.apps/kubernetes-dashboard created service/dashboard-metrics-scraper created deployment.apps/dashboard-metrics-scraper created $ k get pod,svc -n kubernetes-dashboard NAME READY STATUS RESTARTS AGE pod/dashboard-metrics-scraper-79c5968bdc-zq4tc 1/1 Running 0 117s pod/kubernetes-dashboard-7448ffc97b-rwnmp 1/1 Running 0 117s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/dashboard-metrics-scraper ClusterIP 10.100.200.128 <none> 8000/TCP 117s service/kubernetes-dashboard NodePort 10.96.43.126 <none> 443:31010/TCP 117s
访问:http://192.168.211.40:31010/
//创建dashboard的管理用户 $ kubectl create serviceaccount dashboard-admin -n kube-system $ kubectl create clusterrolebinding dashboard-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin $ kubectl get secrets -n kube-system | grep dashboard-admin dashboard-admin-token-lx8th kubernetes.io/service-account-token 3 33s $ kubectl describe secrets dashboard-admin-token-lx8th -n kube-system Name: dashboard-admin-token-lx8th Namespace: kube-system Labels: <none> Annotations: kubernetes.io/service-account.name: dashboard-admin kubernetes.io/service-account.uid: d6a78702-0099-47bc-949c-946f246403a0 Type: kubernetes.io/service-account-token Data ==== ca.crt: 1066 bytes namespace: 11 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjNROWFvUGhIWk9sYzBHT3JvOUJDb2wtX29Tc1Z0blRVUmxpeEhmaUpIUFEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tbHg4dGgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZDZhNzg3MDItMDA5OS00N2JjLTk0OWMtOTQ2ZjI0NjQwM2EwIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.g4B9UQki-7PLBwNsNiE7ppPb8uu0tiAqNBoThREYY4MRoYkxc7Fu9_CtbJZaOjD02iGa5EacsKbG7vmVyrNT_iB1PzOC2ueU5K1QV9M41MftSCw4CBHCgISso3tQDYkTfaRNnWl6weFZqJz3vAQnNX-iOhC7_8KaHzY0qKIahZFvV4j_9-s-a2cxObFp8x_UdKS5sFrZeiu5vz93R8frzuL_3A-UsB1x_k9Ptb9kQieQBV_YCO5qvcdKb3wQUnFYQyZkt05v5yIlLouhNNeQFFJN1f_ycdmoT5yzg2cSM_j1Ls6H92N8SY7R0gG_A14ZQc2hFvxlBRc7F67TIfaWbQ 或者执行 $ kubectl get secret -n kube-system $(kubectl get serviceaccount dashboard-admin -n kube-system -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 --decode
获取 token:
访问
6.2 kubeconfig 访问
//查看刚才创建的token $ kubectl get secrets -n kube-system | grep dashboard dashboard-admin-token-lx8th kubernetes.io/service-account-token 3 13m //查看token的详细信息,会获取token $ kubectl describe secrets -n kube-system dashboard-admin-token-lx8th Name: dashboard-admin-token-lx8th Namespace: kube-system Labels: <none> Annotations: kubernetes.io/service-account.name: dashboard-admin kubernetes.io/service-account.uid: d6a78702-0099-47bc-949c-946f246403a0 Type: kubernetes.io/service-account-token Data ==== namespace: 11 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjNROWFvUGhIWk9sYzBHT3JvOUJDb2wtX29Tc1Z0blRVUmxpeEhmaUpIUFEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tbHg4dGgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZDZhNzg3MDItMDA5OS00N2JjLTk0OWMtOTQ2ZjI0NjQwM2EwIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.g4B9UQki-7PLBwNsNiE7ppPb8uu0tiAqNBoThREYY4MRoYkxc7Fu9_CtbJZaOjD02iGa5EacsKbG7vmVyrNT_iB1PzOC2ueU5K1QV9M41MftSCw4CBHCgISso3tQDYkTfaRNnWl6weFZqJz3vAQnNX-iOhC7_8KaHzY0qKIahZFvV4j_9-s-a2cxObFp8x_UdKS5sFrZeiu5vz93R8frzuL_3A-UsB1x_k9Ptb9kQieQBV_YCO5qvcdKb3wQUnFYQyZkt05v5yIlLouhNNeQFFJN1f_ycdmoT5yzg2cSM_j1Ls6H92N8SY7R0gG_A14ZQc2hFvxlBRc7F67TIfaWbQ ca.crt: 1066 bytes //将token的信息生成一个变量 $ DASH_TOKEN=$(kubectl get secrets -n kube-system dashboard-admin-token-lx8th -o jsonpath={.data.token} | base64 -d) //将k8s集群的配置信息写入到一个文件中,文件可自定义 kubectl config set-cluster kubernetes --server=192.168.211.40:6443 --kubeconfig=/root/.dashboard-admin.conf $ cat /root/.dashboard-admin.conf apiVersion: v1 clusters: - cluster: server: 192.168.211.40:6443 name: kubernetes contexts: null current-context: "" kind: Config preferences: {} users: null $ //将token的信息也写入到文件中(同一个文件) $ kubectl config set-credentials dashboard-admin --token=${DASH_TOKEN} --kubeconfig=/root/.dashboard-admin.conf User "dashboard-admin" set. $ cat /root/.dashboard-admin.conf apiVersion: v1 clusters: - cluster: server: 192.168.211.40:6443 name: kubernetes contexts: null current-context: "" kind: Config preferences: {} users: - name: dashboard-admin user: token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjNROWFvUGhIWk9sYzBHT3JvOUJDb2wtX29Tc1Z0blRVUmxpeEhmaUpIUFEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tbHg4dGgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZDZhNzg3MDItMDA5OS00N2JjLTk0OWMtOTQ2ZjI0NjQwM2EwIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.g4B9UQki-7PLBwNsNiE7ppPb8uu0tiAqNBoThREYY4MRoYkxc7Fu9_CtbJZaOjD02iGa5EacsKbG7vmVyrNT_iB1PzOC2ueU5K1QV9M41MftSCw4CBHCgISso3tQDYkTfaRNnWl6weFZqJz3vAQnNX-iOhC7_8KaHzY0qKIahZFvV4j_9-s-a2cxObFp8x_UdKS5sFrZeiu5vz93R8frzuL_3A-UsB1x_k9Ptb9kQieQBV_YCO5qvcdKb3wQUnFYQyZkt05v5yIlLouhNNeQFFJN1f_ycdmoT5yzg2cSM_j1Ls6H92N8SY7R0gG_A14ZQc2hFvxlBRc7F67TIfaWbQ //用户信息也写入文件中(同一个文件) $ kubectl config set-context dashboard-admin@kubernetes --cluster=kubernetes --user=dashboard-admin --kubeconfig=/root/.dashboard-admin.conf $ cat /root/.dashboard-admin.conf apiVersion: v1 clusters: - cluster: server: 192.168.211.40:6443 name: kubernetes contexts: - context: #添加 cluster: kubernetes #添加 user: dashboard-admin #添加 name: dashboard-admin@kubernetes #添加 current-context: "" kind: Config preferences: {} users: - name: dashboard-admin user: token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjNROWFvUGhIWk9sYzBHT3JvOUJDb2wtX29Tc1Z0blRVUmxpeEhmaUpIUFEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tbHg4dGgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZDZhNzg3MDItMDA5OS00N2JjLTk0OWMtOTQ2ZjI0NjQwM2EwIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.g4B9UQki-7PLBwNsNiE7ppPb8uu0tiAqNBoThREYY4MRoYkxc7Fu9_CtbJZaOjD02iGa5EacsKbG7vmVyrNT_iB1PzOC2ueU5K1QV9M41MftSCw4CBHCgISso3tQDYkTfaRNnWl6weFZqJz3vAQnNX-iOhC7_8KaHzY0qKIahZFvV4j_9-s-a2cxObFp8x_UdKS5sFrZeiu5vz93R8frzuL_3A-UsB1x_k9Ptb9kQieQBV_YCO5qvcdKb3wQUnFYQyZkt05v5yIlLouhNNeQFFJN1f_ycdmoT5yzg2cSM_j1Ls6H92N8SY7R0gG_A14ZQc2hFvxlBRc7F67TIfaWbQ //将上下文的配置信息也写入文件中(同一个文件) $ kubectl config use-context dashboard-admin@kubernetes --kubeconfig=/root/.dashboard-admin.conf $ cat /root/.dashboard-admin.conf apiVersion: v1 clusters: - cluster: server: 192.168.211.40:6443 name: kubernetes contexts: - context: cluster: kubernetes user: dashboard-admin name: dashboard-admin@kubernetes current-context: dashboard-admin@kubernetes #添加dashboard-admin@kubernetes kind: Config preferences: {} users: - name: dashboard-admin user: token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjNROWFvUGhIWk9sYzBHT3JvOUJDb2wtX29Tc1Z0blRVUmxpeEhmaUpIUFEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tbHg4dGgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZDZhNzg3MDItMDA5OS00N2JjLTk0OWMtOTQ2ZjI0NjQwM2EwIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.g4B9UQki-7PLBwNsNiE7ppPb8uu0tiAqNBoThREYY4MRoYkxc7Fu9_CtbJZaOjD02iGa5EacsKbG7vmVyrNT_iB1PzOC2ueU5K1QV9M41MftSCw4CBHCgISso3tQDYkTfaRNnWl6weFZqJz3vAQnNX-iOhC7_8KaHzY0qKIahZFvV4j_9-s-a2cxObFp8x_UdKS5sFrZeiu5vz93R8frzuL_3A-UsB1x_k9Ptb9kQieQBV_YCO5qvcdKb3wQUnFYQyZkt05v5yIlLouhNNeQFFJN1f_ycdmoT5yzg2cSM_j1Ls6H92N8SY7R0gG_A14ZQc2hFvxlBRc7F67TIfaWbQ //最后将配置信息导入到客户端本地 $ sz /root/.dashboard-admin.conf
访问:https://192.168.211.40:31010/
6.3 proxy 访问
出于安全原因,推荐的配置为 Dashboard ServiceAccount 提供对 Kubernetes 资源的有限访问权限。这可以防止secrets或证书等敏感集群数据被意外暴露。
也就是说,要利用所有 Web UI 功能,您需要一个具有管理(超级用户)权限的服务帐户,即具有cluster -admin集群角色的服务帐户。
使用您喜欢的文本编辑器,创建一个admin-user.yml文件:
--- apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard
kubectl apply -f admin-user.yml
Accessing the Kubernetes Dashboard
访问 Kubernetes Dashboard 的推荐方式是通过 Bearer Tokens。这为管理权限提供了极大的灵活性。
要获取 ServiceAccount admin-user的 Bearer Token,请运行以下命令。
kubectl get secret -n kubernetes-dashboard $(kubectl get serviceaccount admin-user -n kubernetes-dashboard -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 --decode
输出:
赋值保存,执行公开 Kubernetes Dashboard 命令:
kubectl proxy
如果您已按照本教程中描述的过程进行操作,终端中将显示一条消息,指示 WebUI 在127.0.0.1:8001可用。出于安全原因,仪表板只能从运行kubectl proxy命令的机器访问。请记住这一点,特别是如果 Kubernetes 安装在远程服务器上。
代理激活后,您可以访问 Web UI,将您喜欢的浏览器指向以下地址:
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy
参考:
部署和访问 Kubernetes 仪表板(Dashboard)
https://github.com/kubernetes/dashboard
Tutorial: Deploy the Kubernetes Dashboard (web UI)
Kubernetes Dashboard | Installation, Tips, and Examples