Convert site to Hugo (#8316)
This commit converts content and layout to use Hugo.
This commit is contained in:
committed by
k8s-ci-robot
parent
7745f0e0c5
commit
7f3b633aa0
@@ -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 %}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user