Convert site to Hugo (#8316)

This commit converts content and layout to use Hugo.
This commit is contained in:
Bjørn Erik Pedersen
2018-05-05 18:00:51 +02:00
committed by k8s-ci-robot
parent 7745f0e0c5
commit 7f3b633aa0
2327 changed files with 10928 additions and 171503 deletions
@@ -0,0 +1,17 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: patch-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: patch-demo-ctr
image: nginx
@@ -0,0 +1,16 @@
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 4 # Update the replicas from 2 to 4
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort: 80
@@ -0,0 +1,16 @@
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8 # Update the version of nginx from 1.7.9 to 1.8
ports:
- containerPort: 80
@@ -0,0 +1,18 @@
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2 # tells deployment to run 2 pods matching the template
template: # create pods using pod definition in this template
metadata:
# unlike pod-nginx.yaml, the name is not included in the meta data as a unique name is
# generated from the deployment name
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
gcePersistentDisk:
pdName: mysql-disk
fsType: ext4
@@ -0,0 +1,16 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql
labels:
app: mysql
data:
master.cnf: |
# Apply this config only on the master.
[mysqld]
log-bin
slave.cnf: |
# Apply this config only on slaves.
[mysqld]
super-read-only
@@ -0,0 +1,52 @@
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
accessModes:
- ReadWriteOnce
storageClassName: ""
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: mysql
spec:
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
@@ -0,0 +1,30 @@
# Headless service for stable DNS entries of StatefulSet members.
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
- name: mysql
port: 3306
clusterIP: None
selector:
app: mysql
---
# Client service for connecting to any MySQL instance for reads.
# For writes, you must instead connect to the master: mysql-0.mysql.
apiVersion: v1
kind: Service
metadata:
name: mysql-read
labels:
app: mysql
spec:
ports:
- name: mysql
port: 3306
selector:
app: mysql
@@ -0,0 +1,164 @@
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 3
template:
metadata:
labels:
app: mysql
annotations:
pod.beta.kubernetes.io/init-containers: '[
{
"name": "init-mysql",
"image": "mysql:5.7",
"command": ["bash", "-c", "
set -ex\n
# Generate mysql server-id from pod ordinal index.\n
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1\n
ordinal=${BASH_REMATCH[1]}\n
echo [mysqld] > /mnt/conf.d/server-id.cnf\n
# Add an offset to avoid reserved server-id=0 value.\n
echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf\n
# Copy appropriate conf.d files from config-map to emptyDir.\n
if [[ $ordinal -eq 0 ]]; then\n
cp /mnt/config-map/master.cnf /mnt/conf.d/\n
else\n
cp /mnt/config-map/slave.cnf /mnt/conf.d/\n
fi\n
"],
"volumeMounts": [
{"name": "conf", "mountPath": "/mnt/conf.d"},
{"name": "config-map", "mountPath": "/mnt/config-map"}
]
},
{
"name": "clone-mysql",
"image": "gcr.io/google-samples/xtrabackup:1.0",
"command": ["bash", "-c", "
set -ex\n
# Skip the clone if data already exists.\n
[[ -d /var/lib/mysql/mysql ]] && exit 0\n
# Skip the clone on master (ordinal index 0).\n
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1\n
ordinal=${BASH_REMATCH[1]}\n
[[ $ordinal -eq 0 ]] && exit 0\n
# Clone data from previous peer.\n
ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql\n
# Prepare the backup.\n
xtrabackup --prepare --target-dir=/var/lib/mysql\n
"],
"volumeMounts": [
{"name": "data", "mountPath": "/var/lib/mysql", "subPath": "mysql"},
{"name": "conf", "mountPath": "/etc/mysql/conf.d"}
]
}
]'
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ALLOW_EMPTY_PASSWORD
value: "1"
ports:
- name: mysql
containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 1
memory: 1Gi
livenessProbe:
exec:
command: ["mysqladmin", "ping"]
initialDelaySeconds: 30
timeoutSeconds: 5
readinessProbe:
exec:
# Check we can execute queries over TCP (skip-networking is off).
command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
initialDelaySeconds: 5
timeoutSeconds: 1
- name: xtrabackup
image: gcr.io/google-samples/xtrabackup:1.0
ports:
- name: xtrabackup
containerPort: 3307
command:
- bash
- "-c"
- |
set -ex
cd /var/lib/mysql
# Determine binlog position of cloned data, if any.
if [[ -f xtrabackup_slave_info ]]; then
# XtraBackup already generated a partial "CHANGE MASTER TO" query
# because we're cloning from an existing slave.
mv xtrabackup_slave_info change_master_to.sql.in
# Ignore xtrabackup_binlog_info in this case (it's useless).
rm -f xtrabackup_binlog_info
elif [[ -f xtrabackup_binlog_info ]]; then
# We're cloning directly from master. Parse binlog position.
[[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1
rm xtrabackup_binlog_info
echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\
MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
fi
# Check if we need to complete a clone by starting replication.
if [[ -f change_master_to.sql.in ]]; then
echo "Waiting for mysqld to be ready (accepting connections)"
until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done
echo "Initializing replication from clone position"
# In case of container restart, attempt this at-most-once.
mv change_master_to.sql.in change_master_to.sql.orig
mysql -h 127.0.0.1 <<EOF
$(<change_master_to.sql.orig),
MASTER_HOST='mysql-0.mysql',
MASTER_USER='root',
MASTER_PASSWORD='',
MASTER_CONNECT_RETRY=10;
START SLAVE;
EOF
fi
# Start a server to send backups when requested by peers.
exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c \
"xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root"
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 100m
memory: 100Mi
volumes:
- name: conf
emptyDir: {}
- name: config-map
configMap:
name: mysql
volumeClaimTemplates:
- metadata:
name: data
annotations:
volume.alpha.kubernetes.io/storage-class: default
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
@@ -0,0 +1,224 @@
---
approvers:
- janetkuo
title: 基于Replication Controller执行滚动升级
---
{{< toc >}}
## 概述
**注**: 创建副本应用的首选方法是使用[Deployment](/docs/api-reference/{{< param "version" >}}/#deployment-v1beta1-apps)Deployment使用[ReplicaSet](/docs/api-reference/{{< param "version" >}}/#replicaset-v1beta1-extensions)来进行副本控制。
更多信息, 查看[使用Deployment运行一个无状态应用](/docs/tasks/run-application/run-stateless-application-deployment/)。
为了在更新服务的同时不中断业务, `kubectl` 支持['滚动更新'](/docs/user-guide/kubectl/v1.6/#rolling-update),它一次更新一个pod,而不是同时停止整个服务。 有关更多信息,请参阅 [滚动更新设计文档](https://git.k8s.io/community/contributors/design-proposals/cli/simple-rolling-update.md) 和 [滚动更新示例](/docs/tasks/run-application/rolling-update-replication-controller/)。
请注意, `kubectl rolling-update` 仅支持Replication Controllers。 但是,如果使用Replication Controllers部署应用,请考虑将其切换到[Deployments](/docs/concepts/workloads/controllers/deployment/). Deployment是一种被推荐使用的更高级别的控制器,它可以对应用进行声明性的自动滚动更新。 如果您仍然希望保留您的Replication Controllers并使用 `kubectl rolling-update`进行滚动更新, 请继续往下阅读:
滚动更新可以对replication controller所管理的Pod的配置进行变更,变更可以通过一个新的配置文件来进行,或者,如果只更新镜像,则可以直接指定新的容器镜像。
滚动更新的工作流程:
1. 通过新的配置创建一个replication controller
2. 在新的控制器上增加副本数,在旧的上面减少副本数,直到副本数达到期望值
3. 删除之前的replication controller
使用`kubectl rolling-update`命令来进行滚动更新:
$ kubectl rolling-update NAME \
([NEW_NAME] --image=IMAGE | -f FILE)
## 通过配置文件更新
通过配置文件来进行滚动更新,需要在`kubectl rolling-update`命令后面带上新的配置文件:
$ kubectl rolling-update NAME -f FILE
这个配置文件必须满足以下条件:
* 指定不同的`metadata.name`
* 至少要修改`spec.selector`中的一个标签值
* `metadata.namespace`字段必须相同
Replication Controllers的配置文件详细介绍见[创建Replication Controllers](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/).
### 示例
// 通过新的配置文件frontend-v2.json来更新frontend-v1的pods
$ kubectl rolling-update frontend-v1 -f frontend-v2.json
// 将frontend-v2.json数据传到标准输入来更新frontend-v1的pods
$ cat frontend-v2.json | kubectl rolling-update frontend-v1 -f -
## 更新容器镜像
仅更新容器镜像的话,可通过如下命令,该命令可以指定一个新的控制器名称(可选),通过`--image`参数来指定新的镜像名称和标签。
$ kubectl rolling-update NAME [NEW_NAME] --image=IMAGE:TAG
`--image`参数仅支持单容器pod,多容器pod使用`--image`参数会返回错误。
如果没有指定 `NEW_NAME` ,新的replication controller创建后会使用一个临时名称,当更新完成,旧的controller被删除后,新的controller名称会被更新成旧的controller名称。
如果`IMAGE:TAG` 和当前值相同,更新就会失败。 因此,我们建议使用版本号来作为标签,而不是使用 `:latest`。从一个 `image:latest`镜像升级到一个新的 `image:latest` 镜像将会失败,即使这两个镜像不是相同的。
所以,我们不建议使用 `:latest` 来作为标签,详细信息见[最佳配置实践](/docs/concepts/configuration/overview/#container-images) 。
### 示例
// 更新frontend-v1的pod到frontend-v2
$ kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2
// 更新frontend的pods,不更改replication controller的名称
$ kubectl rolling-update frontend --image=image:v2
## 必选和可选字段
必选字段:
* `NAME`: 需要进行滚动更新的replication controller名称
下面两个字段选其一:
* `-f FILE`: 新的replication controller的配置文件,JSON或者YAML格式均可。配置文件必须指定一个新的顶层`id`值,且至少包含一个现有`spec.selector`中的键值对。
详细信息见[通过Replication Controller运行无状态应用](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/#replication-controller-configuration-file)。
<br>
<br>
或者:
<br>
<br>
* `--image IMAGE:TAG`: 更新后的镜像的名称和标签。必须和当前的image:tag不同。
可选字段包括:
* `NEW_NAME`: 只和 `--image` 一起使用,不和 `-f FILE` 一起使用。标识新的replication controller的名称。
* `--poll-interval DURATION`: 在更新后轮询控制器状态的间隔时间。有效单位有 `ns` (纳秒),`us``µs`(微秒),`ms`(毫秒),`s`(秒),`m`(分钟)或 `h`(小时)。 单位可以自由组合(例如 `1m30s`)。 默认值为 `3s`
* `--timeout DURATION`: 退出更新之前,等待控制器更新一个pod的最大时间。默认是`5m0s`。有效单位如`--poll-interval`所述。
* `--update-period DURATION`: 更新两个pod之间等待的时间,默认值是`1m0s`。有效单位如`--poll-interval`所述。
有关`kubectl rolling-update`命令的更多信息见[`kubectl`参考](/docs/user-guide/kubectl/v1.6/#rolling-update).
## 实践
现在你运行了一个1.7.9版本的nginx应用:
```yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: my-nginx
spec:
replicas: 5
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
```
要更新到1.9.1版本,你可以使用[`kubectl rolling-update --image`](https://git.k8s.io/community/contributors/design-proposals/cli/simple-rolling-update.md)来指定一个新的镜像:
```shell
$ kubectl rolling-update my-nginx --image=nginx:1.9.1
Created my-nginx-ccba8fbd8cc8160970f63f9a2696fc46
```
在终端上打开另一个窗口 ,你可以看到`kubectl` 给每个pod都增加了一个值为配置文件哈希值的 `deployment` 标签,用来区分新旧pod
```shell
$ kubectl get pods -l app=nginx -L deployment
NAME READY STATUS RESTARTS AGE DEPLOYMENT
my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-k156z 1/1 Running 0 1m ccba8fbd8cc8160970f63f9a2696fc46
my-nginx-ccba8fbd8cc8160970f63f9a2696fc46-v95yh 1/1 Running 0 35s ccba8fbd8cc8160970f63f9a2696fc46
my-nginx-divi2 1/1 Running 0 2h 2d1d7a8f682934a254002b56404b813e
my-nginx-o0ef1 1/1 Running 0 2h 2d1d7a8f682934a254002b56404b813e
my-nginx-q6all 1/1 Running 0 8m 2d1d7a8f682934a254002b56404b813e
```
使用`kubectl rolling-update`可以实时看到更新的进度:
```
Scaling up my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 from 0 to 3, scaling down my-nginx from 3 to 0 (keep 3 pods available, don't exceed 4 pods)
Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 1
Scaling my-nginx down to 2
Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 2
Scaling my-nginx down to 1
Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 up to 3
Scaling my-nginx down to 0
Update succeeded. Deleting old controller: my-nginx
Renaming my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 to my-nginx
replicationcontroller "my-nginx" rolling updated
```
如果遇到问题,你可以中途停止滚动更新,并且使用 `--rollback` 来回滚到以前的版本:
```shell
$ kubectl rolling-update my-nginx --rollback
Setting "my-nginx" replicas to 1
Continuing update with existing controller my-nginx.
Scaling up nginx from 1 to 1, scaling down my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 from 1 to 0 (keep 1 pods available, don't exceed 2 pods)
Scaling my-nginx-ccba8fbd8cc8160970f63f9a2696fc46 down to 0
Update succeeded. Deleting my-nginx-ccba8fbd8cc8160970f63f9a2696fc46
replicationcontroller "my-nginx" rolling updated
```
这个例子说明容器的不变性是个巨大的优点。
如果你不仅仅是需要更新镜像,(例如,更新命令参数,环境变量等),你可以创建一个新的replication controller配置文件,包含一个新的名称和不同的标签值,例如:
```yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: my-nginx-v4
spec:
replicas: 5
selector:
app: nginx
deployment: v4
template:
metadata:
labels:
app: nginx
deployment: v4
spec:
containers:
- name: nginx
image: nginx:1.9.2
args: ["nginx", "-T"]
ports:
- containerPort: 80
```
然后使用它来进行更新:
```shell
$ kubectl rolling-update my-nginx -f ./nginx-rc.yaml
Created my-nginx-v4
Scaling up my-nginx-v4 from 0 to 5, scaling down my-nginx from 4 to 0 (keep 4 pods available, don't exceed 5 pods)
Scaling my-nginx-v4 up to 1
Scaling my-nginx down to 3
Scaling my-nginx-v4 up to 2
Scaling my-nginx down to 2
Scaling my-nginx-v4 up to 3
Scaling my-nginx down to 1
Scaling my-nginx-v4 up to 4
Scaling my-nginx down to 0
Scaling my-nginx-v4 up to 5
Update succeeded. Deleting old controller: my-nginx
replicationcontroller "my-nginx-v4" rolling updated
```
## 故障分析
如果更新过程中,达到超时时长`timeout`后还没更新完成,则更新会失败。这时,一些pod会属于新的replication controller,一些会属于旧的。
如果更新失败,可以尝试使用同样的命令来继续更新过程。
在尝试更新之前如果需要回滚到之前的状态,可在之前的命令后面添加`--rollback=true`参数,这将回退所有的更改。
@@ -0,0 +1,227 @@
---
title: 运行一个单实例有状态应用
content_template: templates/tutorial
---
{{% capture overview %}}
本文介绍在Kubernetes中使用PersistentVolume和Deployment如何运行一个单实例有状态应用. 该应用是MySQL.
{{% /capture %}}
{{% capture objectives %}}
* 在环境中通过磁盘创建一个PersistentVolume.
* 创建一个MySQL Deployment.
* 在集群内以一个已知的DNS名将MySQL暴露给其他pods.
{{% /capture %}}
{{% capture prerequisites %}}
* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
* 为了数据持久性我们将在环境上通过磁盘创建一个持久卷. 环境支持的类型见这里[here](/docs/user-guide/persistent-volumes/#types-of-persistent-volumes). 本篇文档将介绍 `GCEPersistentDisk` . `GCEPersistentDisk`卷只能工作在Google Compute Engine平台上.
{{% /capture %}}
{{% capture lessoncontent %}}
## 在环境中设置一个磁盘
你可以为有状态的应用使用任何类型的持久卷. 有关支持环境的磁盘列表,请参考持久卷类型[Types of Persistent Volumes](/docs/user-guide/persistent-volumes/#types-of-persistent-volumes). 对于Google Compute Engine, 请运行:
```
gcloud compute disks create --size=20GB mysql-disk
```
接下来创建一个指向刚创建的 `mysql-disk`磁盘的PersistentVolume. 下面是一个PersistentVolume的配置文件,它指向上面创建的Compute Engine磁盘:
{{< code file="gce-volume.yaml" >}}
注意`pdName: mysql-disk` 这行与Compute Engine环境中的磁盘名称相匹配. 有关为其
他环境编写PersistentVolume配置文件的详细信息,请参见持久卷[Persistent Volumes](/docs/concepts/storage/persistent-volumes/).
创建持久卷:
```
kubectl create -f https://k8s.io/docs/tasks/run-application/gce-volume.yaml
```
## 部署MySQL
通过创建Kubernetes Deployment并使用PersistentVolumeClaim将其连接到现已存在的PersistentVolume上来运行一个有状态的应用. 例如, 下面这个YAML文件描述了一个运行MySQL
并引用PersistentVolumeClaim的Deployment. 该文件定义了一个volume其挂载目录为/var/lib/mysql, 然后创建一个内存为20G的卷的PersistentVolumeClaim. 此申领可以通过任
何符合需求的卷来满足, 在本例中满足上面创建的卷.
注意: 在配置的yaml文件中定义密码的做法是不安全的. 具体安全解决方案请参考
[Kubernetes Secrets](/docs/concepts/configuration/secret/).
{{< code file="mysql-deployment.yaml" >}}
1. 部署YAML文件中定义的内容:
kubectl create -f https://k8s.io/docs/tasks/run-application/mysql-deployment.yaml
1. 展示Deployment相关信息:
kubectl describe deployment mysql
Name: mysql
Namespace: default
CreationTimestamp: Tue, 01 Nov 2016 11:18:45 -0700
Labels: app=mysql
Annotations: deployment.kubernetes.io/revision=1
Selector: app=mysql
Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType: Recreate
MinReadySeconds: 0
Pod Template:
Labels: app=mysql
Containers:
mysql:
Image: mysql:5.6
Port: 3306/TCP
Environment:
MYSQL_ROOT_PASSWORD: password
Mounts:
/var/lib/mysql from mysql-persistent-storage (rw)
Volumes:
mysql-persistent-storage:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: mysql-pv-claim
ReadOnly: false
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
Progressing True ReplicaSetUpdated
OldReplicaSets: <none>
NewReplicaSet: mysql-63082529 (1/1 replicas created)
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
33s 33s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mysql-63082529 to 1
1. 列举出Deployment创建的pods:
kubectl get pods -l app=mysql
NAME READY STATUS RESTARTS AGE
mysql-63082529-2z3ki 1/1 Running 0 3m
1. 查看持久卷:
kubectl describe pv mysql-pv
Name: mysql-pv
Labels: <none>
Status: Bound
Claim: default/mysql-pv-claim
Reclaim Policy: Retain
Access Modes: RWO
Capacity: 20Gi
Message:
Source:
Type: GCEPersistentDisk (a Persistent Disk resource in Google Compute Engine)
PDName: mysql-disk
FSType: ext4
Partition: 0
ReadOnly: false
No events.
1. 查看PersistentVolumeClaim:
kubectl describe pvc mysql-pv-claim
Name: mysql-pv-claim
Namespace: default
Status: Bound
Volume: mysql-pv
Labels: <none>
Capacity: 20Gi
Access Modes: RWO
No events.
## 访问MySQL实例
前面YAML文件中创建了一个允许集群内其他pods访问数据库的服务. 该服务中选项
`clusterIP: None` 让服务DNS名称直接解析为Pod的IP地址. 当在一个服务下只有一个pod
并且不打算增加pods的数量这是最好的.
运行MySQL客户端以连接到服务器:
```
kubectl run -it --rm --image=mysql:5.6 mysql-client -- mysql -h <pod-ip> -p <password>
```
此命令在集群内创建一个新的Pod并运行MySQL客户端,并通过服务将其连接到服务器.如果连接成功,你就知道有状态的MySQL database正处于运行状态.
```
Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
mysql>
```
## 更新
Deployment中镜像或其他部分同往常一样可以通过 `kubectl apply` 命令更新. 以下是
特定于有状态应用的一些注意事项:
* 不要弹性伸缩. 弹性伸缩仅适用于单实例应用. 下层的PersistentVolume仅只能挂载一个pod. 对于集群级有状态应用, 请参考StatefulSet文档
[StatefulSet documentation](/docs/concepts/workloads/controllers/statefulset/).
* 在Deployment的YAML文件中使用 `strategy:` `type: Recreate` . 该选项指示Kubernetes不使用滚动升级. 滚动升级将无法工作, 由于一次不能运行多个pod. 在更新配置文件
创建一个新的pod前 `Recreate`策略将先停止第一个pod.
## 删除deployment
通过名称删除部署的对象:
```
kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv
```
如果使用Compute Engine磁盘,也可以使用如下命令:
```
gcloud compute disks delete mysql-disk
```
{{% /capture %}}
{{% capture whatsnext %}}
* 了解更多Deployment对象请参考 [Deployment objects](/docs/concepts/workloads/controllers/deployment/).
* 了解更多Deployment应用请参考 [Deploying applications](/docs/user-guide/deploying-applications/)
* kubectl run文档请参考[kubectl run documentation](/docs/user-guide/kubectl/v1.6/#run)
* 卷和持久卷请参考[Volumes](/docs/concepts/storage/volumes/) and [Persistent Volumes](/docs/concepts/storage/persistent-volumes/)
{{% /capture %}}
@@ -0,0 +1,144 @@
---
title: 使用Deployment运行一个无状态应用
content_template: templates/tutorial
---
{{% capture overview %}}
本文介绍通过Kubernetes Deployment对象如何去运行一个应用.
{{% /capture %}}
{{% capture objectives %}}
* 创建一个nginx deployment.
* 使用kubectl列举关于deployment信息.
* 更新deployment.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture lessoncontent %}}
## 创建和探究一个nginx deployment
你可以通过创建一个Kubernetes Deployment对象来运行一个应用, 可以在一个YAML文件中描述Deployment. 例如, 下面这个YAML文件描述了一个运行nginx:1.7.9 Docker镜像的Deployment:
{{< code file="deployment.yaml" >}}
1. 通过YAML文件创建一个Deployment:
kubectl create -f https://k8s.io/docs/tasks/run-application/deployment.yaml
1. 展示Deployment相关信息:
kubectl describe deployment nginx-deployment
user@computer:~/website$ kubectl describe deployment nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Tue, 30 Aug 2016 18:11:37 -0700
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision=1
Selector: app=nginx
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.7.9
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-1771418926 (2/2 replicas created)
No events.
1. 列出deployment创建的pods:
kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-1771418926-7o5ns 1/1 Running 0 16h
nginx-deployment-1771418926-r18az 1/1 Running 0 16h
1. 展示某一个pod信息:
kubectl describe pod <pod-name>
该处 `<pod-name>` 指某一pod的名称.
## 更新deployment
你可以通过更新一个新的YAML文件来更新deployment. 下面的YAML文件指定该deployment镜像更新为nginx 1.8.
{{< code file="deployment-update.yaml" >}}
1. 应用新的YAML:
kubectl apply -f https://k8s.io/docs/tutorials/stateless-application/deployment-update.yaml
1. 查看该deployment创建的pods以新的名称同时删除旧的pods:
kubectl get pods -l app=nginx
## 通过增加副本数来弹缩应用
你可以通过应用新的YAML文件来增加Deployment中pods的数量. 该YAML文件将`replicas`设置为4, 指定该Deployment应有4个pods:
{{< code file="deployment-scale.yaml" >}}
1. 应用新的YAML文件:
kubectl apply -f https://k8s.io/docs/tutorials/stateless-application/deployment-scale.yaml
1. 验证Deployment有4个pods:
kubectl get pods -l app=nginx
输出的结果类似于:
NAME READY STATUS RESTARTS AGE
nginx-deployment-148880595-4zdqq 1/1 Running 0 25s
nginx-deployment-148880595-6zgi1 1/1 Running 0 25s
nginx-deployment-148880595-fxcez 1/1 Running 0 2m
nginx-deployment-148880595-rwovn 1/1 Running 0 2m
## 删除deployment
通过名称删除deployment:
kubectl delete deployment nginx-deployment
## ReplicationControllers -- 旧的方式
创建一个多副本应用首选方法是使用Deployment,反过来使用ReplicaSet. 在Deployment和ReplicaSet加入到Kubernetes之前, 多副本应用通过[ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/)来配置.
{{% /capture %}}
{{% capture whatsnext %}}
* 了解更多 [Deployment objects](/docs/concepts/workloads/controllers/deployment/).
{{% /capture %}}
@@ -0,0 +1,90 @@
---
approvers:
- bprashanth
- enisoc
- erictune
- foxish
- janetkuo
- kow3ns
- smarterclayton
title: 弹缩StatefulSet
content_template: templates/task
---
{{% capture overview %}}
本文介绍如何弹缩StatefulSet.
{{% /capture %}}
{{% capture prerequisites %}}
* StatefulSets仅适用于Kubernetes1.5及以上版本.
* **不是所有Stateful应用都适合弹缩.** 在弹缩前您的应用前. 您必须充分了解您的应用, 不适当的弹缩StatefulSet或许会造成应用自身功能的不稳定.
* 仅当您确定该Stateful应用的集群是完全健康才可执行弹缩操作.
{{% /capture %}}
{{% capture steps %}}
## 使用 `kubectl` 弹缩StatefulSets
弹缩请确认 `kubectl` 已经升级到Kubernetes1.5及以上版本. 如果不确定, 执行 `kubectl version` 命令并检查使用的 `Client Version`.
### `kubectl 弹缩`
首先, 找到您想要弹缩的StatefulSet. 记住, 您需先清楚是否能弹缩该应用.
```shell
kubectl get statefulsets <stateful-set-name>
```
改变StatefulSet副本数量:
```shell
kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
```
### 可使用其他命令: `kubectl apply` / `kubectl edit` / `kubectl patch`
另外, 您可以 [in-place updates](/docs/concepts/cluster-administration/manage-deployment/#in-place-updates-of-resources) StatefulSets.
如果您的StatefulSet开始由 `kubectl apply``kubectl create --save-config` 创建,更新StatefulSet manifests中的 `.spec.replicas`, 然后执行命令 `kubectl apply`:
```shell
kubectl apply -f <stateful-set-file-updated>
```
除此之外, 可以通过命令 `kubectl edit` 编辑该字段:
```shell
kubectl edit statefulsets <stateful-set-name>
```
或使用 `kubectl patch`:
```shell
kubectl patch statefulsets <stateful-set-name> -p '{"spec":{"replicas":<new-replicas>}}'
```
## 排查故障
### 缩容工作不正常
当Stateful管理下的任何一个Pod不健康时您不能缩容该StatefulSet. 仅当Stateful下的所有Pods都处于运行和ready状态后才可缩容.
当一个StatefulSet的size > 1, 如果有一个Pod不健康, 没有办法让Kubernetes知道是否是由于永久性故障还是瞬态(升级/维护/节点重启)导致. 如果该Pod不健康是由于永久性
故障导致, 则在不纠正该故障的情况下进行缩容可能会导致一种状态, 即StatefulSet下的Pod数量低于应正常运行的副本数. 这也许会导致StatefulSet不可用.
如果由于瞬态故障而导致Pod不健康,并且Pod可能再次可用,那么瞬态错误可能会干扰您对
StatefulSet的扩容/缩容操作. 一些分布式数据库在节点加入和同时离开时存在问题. 在
这些情况下,最好是在应用级别进行弹缩操作, 并且只有在您确保Stateful应用的集群是完全健康时才执行弹缩.
{{% /capture %}}
{{% capture whatsnext %}}
了解更多 [deleting a StatefulSet](/docs/tasks/manage-stateful-set/deleting-a-statefulset/).
{{% /capture %}}